diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 96969e2b21..84da4a60b3 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -16,21 +16,27 @@ HOW TO WRITE A GOOD PULL REQUEST? --> ### What does this PR do? - + ### Closes Issue(s) Closes # - ### Motivation - -### More +### How to test + + + +### More - [ ] Added/updated documentation diff --git a/.github/actions/merge-branches/action.yml b/.github/actions/merge-branches/action.yml index ea8fc99e42..70d0ddabcc 100644 --- a/.github/actions/merge-branches/action.yml +++ b/.github/actions/merge-branches/action.yml @@ -1,9 +1,6 @@ name: Merge branches -on: - workflow_call: - runs: - using: "composite" + using: composite steps: - name: Checkout ${{ github.event.pull_request.base.ref || 'master' }} uses: actions/checkout@v4 diff --git a/.github/actions/upload-blob-report/action.yml b/.github/actions/upload-blob-report/action.yml new file mode 100644 index 0000000000..1e2c98ef1f --- /dev/null +++ b/.github/actions/upload-blob-report/action.yml @@ -0,0 +1,36 @@ +name: Upload blob report +description: Merge and upload the blob report to GitHub Actions Artifacts +runs: + using: composite + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - name: Install dependencies + shell: bash + working-directory: ./bigbluebutton-tests/playwright + run: npm ci + - name: Merge artifacts + uses: actions/upload-artifact/merge@v4 + with: + name: all-blob-reports + pattern: blob-report-* + delete-merged: true + - name: Download all blob reports from GitHub Actions Artifacts + uses: actions/download-artifact@v4 + with: + name: all-blob-reports + path: bigbluebutton-tests/playwright/all-blob-reports + - name: Merge into HTML Report + shell: bash + working-directory: ./bigbluebutton-tests/playwright + run: npx playwright merge-reports --reporter html ./all-blob-reports + - name: Upload HTML tests report + uses: actions/upload-artifact@v4 + with: + name: tests-report + overwrite: true + path: | + bigbluebutton-tests/playwright/playwright-report + bigbluebutton-tests/playwright/test-results diff --git a/.github/workflows/automated-tests-publish-results.yml b/.github/workflows/automated-tests-publish-results.yml index 08a4f6a870..5464457f65 100644 --- a/.github/workflows/automated-tests-publish-results.yml +++ b/.github/workflows/automated-tests-publish-results.yml @@ -5,40 +5,67 @@ on: - Automated tests types: - completed - + - requested +env: + isCompleted: ${{ github.event.workflow_run.status == 'completed' }} jobs: get-pr-data: runs-on: ubuntu-latest + concurrency: + group: github-api-request + cancel-in-progress: false if: ${{ github.event.workflow_run.event == 'pull_request' }} outputs: - pr-number: ${{ steps.set-env.outputs.pr-number }} - workflow-id: ${{ steps.set-env.outputs.workflow-id }} + pr-number: ${{ steps.pr.outputs.result || steps.set-env.outputs.pr-number }} + workflow-id: ${{ github.event.workflow_run.id || steps.set-env.outputs.workflow-id }} steps: - # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow - - name: Download artifact - uses: actions/github-script@v6 + - name: Find associated pull request + if: ${{ !fromJson(env.isCompleted) }} + id: pr + uses: actions/github-script@v7 with: script: | - let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - - let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { - return artifact.name == "pr-comment-data" - })[0]; - let download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: 'zip', - }); - let fs = require('fs'); - fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr-comment-data.zip`, Buffer.from(download.data)); + const response = await github.rest.search.issuesAndPullRequests({ + q: 'repo:${{ github.repository }} is:pr sha:${{ github.event.workflow_run.head_sha }}', + per_page: 1, + }) + const items = response.data.items + if (items.length < 1) { + console.error('No PRs found') + return + } + const pullRequestNumber = items[0].number + return pullRequestNumber + - name: Download PR artifact + if: ${{ fromJson(env.isCompleted) }} + uses: actions/github-script@v7 + with: + script: | + try { + let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { + return artifact.name == "pr-comment-data" + })[0]; + let download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + let fs = require('fs'); + fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr-comment-data.zip`, Buffer.from(download.data)); + } catch (error) { + console.log('No artifact found'); + } - name: Unzip artifact + if: ${{ fromJson(env.isCompleted) }} run: unzip pr-comment-data.zip - - name: Set env variables + - name: Set env variables from artifact + if: ${{ fromJson(env.isCompleted) }} id: set-env run: | echo "pr-number=$(cat ./pr_number)" >> $GITHUB_OUTPUT @@ -50,7 +77,7 @@ jobs: needs: get-pr-data steps: - name: Find Comment - uses: peter-evans/find-comment@v2 + uses: peter-evans/find-comment@v3 id: fc with: issue-number: ${{ needs.get-pr-data.outputs.pr-number }} @@ -58,7 +85,7 @@ jobs: body-includes: Automated tests Summary - name: Remove previous comment if: steps.fc.outputs.comment-id != '' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | github.rest.issues.deleteComment({ @@ -66,17 +93,25 @@ jobs: repo: context.repo.repo, comment_id: ${{ steps.fc.outputs.comment-id }} }) + - name: In progress tests comment + if: ${{ !fromJson(env.isCompleted) }} + uses: peter-evans/create-or-update-comment@v4 + with: + issue-number: ${{ needs.get-pr-data.outputs.pr-number }} + body: | +

Automated tests Summary

+

:hourglass_flowing_sand: Tests are running...

- name: Passing tests comment if: ${{ github.event.workflow_run.conclusion == 'success' }} - uses: peter-evans/create-or-update-comment@v2 + uses: peter-evans/create-or-update-comment@v4 with: issue-number: ${{ needs.get-pr-data.outputs.pr-number }} body: |

Automated tests Summary

:white_check_mark: All the CI tests have passed!

- name: Failing tests comment - if: ${{ github.event.workflow_run.conclusion == 'failure' }} - uses: peter-evans/create-or-update-comment@v2 + if: ${{ github.event.workflow_run.conclusion != 'success' && fromJson(env.isCompleted) }} + uses: peter-evans/create-or-update-comment@v4 with: issue-number: ${{ needs.get-pr-data.outputs.pr-number }} body: | diff --git a/.github/workflows/automated-tests.yml b/.github/workflows/automated-tests.yml index 5f2a5cf8f9..492d775101 100644 --- a/.github/workflows/automated-tests.yml +++ b/.github/workflows/automated-tests.yml @@ -8,6 +8,7 @@ on: paths-ignore: - "docs/**" - "**/*.md" + - "bigbluebutton-html5/public/locales/*.json" pull_request: types: [opened, synchronize, reopened] paths-ignore: @@ -63,7 +64,7 @@ jobs: - package: bbb-fsesl-akka cache-files-list: akka-bbb-fsesl bbb-common-message - package: bbb-html5 - build-list: bbb-html5-nodejs bbb-html5 + build-list: bbb-html5 cache-files-list: bigbluebutton-html5 - package: bbb-freeswitch build-list: bbb-freeswitch-core bbb-freeswitch-sounds @@ -115,6 +116,7 @@ jobs: shard: [1, 2, 3, 4, 5, 6, 7, 8] env: shard: ${{ matrix.shard }}/8 + MATRIX_SHARD_UNDERSCORED: ${{ matrix.shard }}_8 steps: - uses: actions/checkout@v4 - name: Merge branches @@ -265,10 +267,11 @@ jobs: command: | sudo -i < /etc/apt/sources.list.d/bigbluebutton.list||g" | bash -s -- -v jammy-30-dev -s bbb-ci.test -j -d /certs/ bbb-conf --salt bbbci sed -i "s/\"minify\": true,/\"minify\": false,/" /usr/share/etherpad-lite/settings.json + sudo yq e -i '.log_level = "TRACE"' /usr/share/bbb-graphql-middleware/config.yml bbb-conf --restart EOF - name: List systemctl services @@ -314,7 +317,7 @@ jobs: find $HOME/.cache/ms-playwright -name libnssckbi.so -exec rm {} \; -exec ln -s /usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-trust.so {} \; npm run test-firefox-ci -- --shard ${{ env.shard }} ' - - if: always() && github.event_name == 'pull_request' + - if: always() name: Upload blob report to GitHub Actions Artifacts uses: actions/upload-artifact@v4 with: @@ -344,17 +347,16 @@ jobs: chmod a+r -R /home/runner/work/bigbluebutton/bigbluebutton/configs bbb-conf --zip ls -t /root/*.tar.gz | head -1 | xargs -I '{}' cp '{}' /home/runner/work/bigbluebutton/bigbluebutton/bbb-logs.tar.gz - echo "MATRIX_SHARD=${{ matrix.shard }}_8" >> $GITHUB_ENV EOF - if: failure() uses: actions/upload-artifact@v4 with: - name: bbb-configs-${{ env.MATRIX_SHARD }} + name: bbb-configs-${{ env.MATRIX_SHARD_UNDERSCORED }} path: configs - if: failure() uses: actions/upload-artifact@v4 with: - name: bbb-logs-${{ env.MATRIX_SHARD }} + name: bbb-logs-${{ env.MATRIX_SHARD_UNDERSCORED }} path: ./bbb-logs.tar.gz upload-report: if: always() && !contains(github.event.head_commit.message, 'Merge pull request') @@ -364,39 +366,14 @@ jobs: hasReportData: ${{ needs.install-and-run-tests.result == 'success' || needs.install-and-run-tests.result == 'failure' }} steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 18 - - name: Install dependencies + - name: Upload blob report if: ${{ env.hasReportData }} - working-directory: ./bigbluebutton-tests/playwright - run: npm ci - - name: Merge artifacts - uses: actions/upload-artifact/merge@v4 + uses: ./.github/actions/upload-blob-report + - name: Remove unnecessary artifact + uses: geekyeggo/delete-artifact@v5 with: name: all-blob-reports - pattern: blob-report-* - delete-merged: true - - name: Download all blob reports from GitHub Actions Artifacts - if: ${{ env.hasReportData }} - uses: actions/download-artifact@v4 - with: - pattern: all-blob-reports-* - path: bigbluebutton-tests/playwright/all-blob-reports - merge-multiple: true - - name: Merge into HTML Report - if: ${{ env.hasReportData }} - working-directory: ./bigbluebutton-tests/playwright - run: npx playwright merge-reports --reporter html ./all-blob-reports - - name: Upload HTML tests report - if: ${{ env.hasReportData }} - uses: actions/upload-artifact@v4 - with: - name: tests-report - overwrite: true - path: | - bigbluebutton-tests/playwright/playwright-report - bigbluebutton-tests/playwright/test-results + failOnError: false - name: Write PR data for auto-comment if: github.event_name == 'pull_request' working-directory: ./ diff --git a/.github/workflows/check-merge-conflict.yml b/.github/workflows/check-merge-conflict.yml index e857e90b10..3e41caabef 100644 --- a/.github/workflows/check-merge-conflict.yml +++ b/.github/workflows/check-merge-conflict.yml @@ -12,8 +12,11 @@ permissions: jobs: main: permissions: - pull-requests: write # for eps1lon/actions-label-merge-conflict to label PRs + pull-requests: write # for eps1lon/actions-label-merge-conflict to label PRs runs-on: ubuntu-latest + concurrency: + group: github-api-request + cancel-in-progress: false steps: - name: Check for dirty pull requests uses: eps1lon/actions-label-merge-conflict@v3 @@ -21,6 +24,6 @@ jobs: dirtyLabel: "status: conflict" repoToken: "${{ secrets.GITHUB_TOKEN }}" commentOnDirty: | - This pull request has conflicts ☹ - Please resolve those so we can review the pull request. - Thanks. + This pull request has conflicts ☹ + Please resolve those so we can review the pull request. + Thanks. diff --git a/.github/workflows/ts-code-compilation.yml b/.github/workflows/ts-code-compilation.yml index 2b3a78ee23..cfcbfea724 100644 --- a/.github/workflows/ts-code-compilation.yml +++ b/.github/workflows/ts-code-compilation.yml @@ -28,11 +28,9 @@ jobs: fetch-depth: 1 - name: Merge branches uses: ./.github/actions/merge-branches - - name: install meteor - run: curl https://install.meteor.com/ | sh - - name: run meteor npm install + - name: run npm ci working-directory: bigbluebutton-html5 - run: meteor npm install + run: npm ci - name: typescript code compilation working-directory: bigbluebutton-html5 run: npx tsc diff --git a/.github/workflows/ts-code-validation.yml b/.github/workflows/ts-code-validation.yml index 7c50f75610..f81a1704e9 100644 --- a/.github/workflows/ts-code-validation.yml +++ b/.github/workflows/ts-code-validation.yml @@ -28,11 +28,9 @@ jobs: fetch-depth: 1 - name: Merge branches uses: ./.github/actions/merge-branches - - name: install meteor - run: curl https://install.meteor.com/ | sh - - name: run meteor npm install + - name: install npm dependencies working-directory: bigbluebutton-html5 - run: meteor npm install + run: npm ci - name: typescript code validation with eslint working-directory: bigbluebutton-html5 run: npx eslint . --ext .ts,.tsx diff --git a/.gitignore b/.gitignore index d2d29bd333..8f6d25f360 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ bbb-presentation-video.zip bbb-presentation-video bbb-graphql-actions-adapter-server/ bigbluebutton-html5/public/locales/index.json +node_modules diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6a8b70a7f8..1123ae1999 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,7 +12,7 @@ stages: # define which docker image to use for builds default: - image: bigbluebutton/bbb-build:v3.0.x-release--2023-09-26-152524 + image: bigbluebutton/bbb-build:v3.0.x-release--2024-08-30-014114 # This stage uses git to find out since when each package has been unmodified. # it then checks an API endpoint on the package server to find out for which of diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/ApiService.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/ApiService.scala index 224335c05c..ecd382e69b 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/ApiService.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/ApiService.scala @@ -4,8 +4,10 @@ import org.apache.pekko.http.scaladsl.model._ import org.apache.pekko.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import org.apache.pekko.http.scaladsl.server.Directives._ import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.service.{ HealthzService, MeetingInfoService, PubSubReceiveStatus, PubSubSendStatus, RecordingDBSendStatus } +import org.bigbluebutton.core.api.{ ApiResponseFailure, ApiResponseSuccess, UserInfosApiMsg } +import org.bigbluebutton.service.{ HealthzService, MeetingInfoService, PubSubReceiveStatus, PubSubSendStatus, RecordingDBSendStatus, UserInfoService } import spray.json._ + import scala.concurrent._ import ExecutionContext.Implicits.global @@ -63,7 +65,7 @@ trait JsonSupportProtocolMeetingInfoResponse extends SprayJsonSupport with Defau implicit val meetingInfoResponseJsonFormat = jsonFormat1(MeetingInfoResponse) } -class ApiService(healthz: HealthzService, meetingInfoz: MeetingInfoService) +class ApiService(healthz: HealthzService, meetingInfoz: MeetingInfoService, userInfoService: UserInfoService) extends JsonSupportProtocolHealthResponse with JsonSupportProtocolMeetingInfoResponse { @@ -124,5 +126,21 @@ class ApiService(healthz: HealthzService, meetingInfoz: MeetingInfoService) } complete(entityFuture) } + } ~ + path("userInfo") { + (headerValueByName("x-session-token") & headerValueByName("user-agent")) { (sessionToken, userAgent) => + get { + val entityFuture = userInfoService.getUserInfo(sessionToken).map { + case ApiResponseSuccess(msg, userInfos: UserInfosApiMsg) => + val responseMap = userInfoService.generateResponseMap(userInfos) + userInfoService.createHttpResponse(StatusCodes.OK, responseMap) + + case ApiResponseFailure(msg, arg) => + userInfoService.createHttpResponse(StatusCodes.OK, Map("response" -> "unauthorized", "message" -> msg)) + } + + complete(entityFuture) + } + } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/Boot.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/Boot.scala index 0a85bcd0bf..8368f86009 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/Boot.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/Boot.scala @@ -12,7 +12,7 @@ import org.bigbluebutton.core2.AnalyticsActor import org.bigbluebutton.core2.FromAkkaAppsMsgSenderActor import org.bigbluebutton.endpoint.redis.{AppsRedisSubscriberActor, ExportAnnotationsActor, GraphqlConnectionsActor, LearningDashboardActor, RedisRecorderActor} import org.bigbluebutton.common2.bus.IncomingJsonMessageBus -import org.bigbluebutton.service.{HealthzService, MeetingInfoActor, MeetingInfoService} +import org.bigbluebutton.service.{HealthzService, MeetingInfoActor, MeetingInfoService, UserInfoService} object Boot extends App with SystemConfiguration { @@ -50,8 +50,6 @@ object Boot extends App with SystemConfiguration { val meetingInfoService = MeetingInfoService(system, meetingInfoActorRef) - val apiService = new ApiService(healthzService, meetingInfoService) - val redisRecorderActor = system.actorOf( RedisRecorderActor.props(system, redisConfig, healthzService), "redisRecorderActor" @@ -95,6 +93,9 @@ object Boot extends App with SystemConfiguration { val bbbActor = system.actorOf(BigBlueButtonActor.props(system, eventBus, bbbMsgBus, outGW, healthzService), "bigbluebutton-actor") eventBus.subscribe(bbbActor, meetingManagerChannel) + val userInfoService = UserInfoService(system, bbbActor) + val apiService = new ApiService(healthzService, meetingInfoService, userInfoService) + val redisMessageHandlerActor = system.actorOf(ReceivedJsonMsgHandlerActor.props(bbbMsgBus, incomingJsonMessageBus)) incomingJsonMessageBus.subscribe(redisMessageHandlerActor, toAkkaAppsJsonChannel) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/ClientSettings.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/ClientSettings.scala index bec18e1f6a..68e1705923 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/ClientSettings.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/ClientSettings.scala @@ -39,7 +39,7 @@ object ClientSettings extends SystemConfiguration { } ) - //Remove `:private` once it's used only by Meteor internal configs + //Remove `:private` once it's used only by HTML5 client's internal configs clientSettingsFromFile -= "private" } @@ -140,26 +140,26 @@ object ClientSettings extends SystemConfiguration { } yield { if (dataChannel.contains("name")) { val channelName = dataChannel("name").toString - val writePermission = { - if (dataChannel.contains("writePermission")) { - dataChannel("writePermission") match { + val pushPermission = { + if (dataChannel.contains("pushPermission")) { + dataChannel("pushPermission") match { case wPerm: List[String] => wPerm case _ => { - logger.warn(s"Invalid writePermission for channel $channelName in plugin $pluginName") + logger.warn(s"Invalid pushPermission for channel $channelName in plugin $pluginName") List() } } } else { - logger.warn(s"Missing config writePermission for channel $channelName in plugin $pluginName") + logger.warn(s"Missing config pushPermission for channel $channelName in plugin $pluginName") List() } } - val deletePermission = { - if (dataChannel.contains("deletePermission")) { - dataChannel("deletePermission") match { + val replaceOrDeletePermission = { + if (dataChannel.contains("replaceOrDeletePermission")) { + dataChannel("replaceOrDeletePermission") match { case dPerm: List[String] => dPerm case _ => { - logger.warn(s"Invalid deletePermission for channel $channelName in plugin $pluginName") + logger.warn(s"Invalid replaceOrDeletePermission for channel $channelName in plugin $pluginName") List() } } @@ -168,7 +168,7 @@ object ClientSettings extends SystemConfiguration { } } - pluginDataChannels += (channelName -> DataChannel(channelName, writePermission, deletePermission)) + pluginDataChannels += (channelName -> DataChannel(channelName, pushPermission, replaceOrDeletePermission)) } } case _ => logger.warn(s"Plugin $pluginName has an invalid dataChannels format") @@ -184,7 +184,7 @@ object ClientSettings extends SystemConfiguration { pluginsFromConfig } - case class DataChannel(name: String, writePermission: List[String], deletePermission: List[String]) + case class DataChannel(name: String, pushPermission: List[String], replaceOrDeletePermission: List[String]) case class Plugin(name: String, url: String, dataChannels: Map[String, DataChannel]) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/LockSettingsUtil.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/LockSettingsUtil.scala index 69ddbf8e74..a419519b4f 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/LockSettingsUtil.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/LockSettingsUtil.scala @@ -1,9 +1,12 @@ package org.bigbluebutton -import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, MessageTypes, MuteUserInVoiceConfSysMsg, MuteUserInVoiceConfSysMsgBody, Routing } +import org.apache.pekko.actor.ActorContext + +import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, MessageTypes, Routing } import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } import org.bigbluebutton.core2.{ MeetingStatus2x } import org.bigbluebutton.core.apps.webcam.CameraHdlrHelpers +import org.bigbluebutton.core.apps.voice.VoiceApp import org.bigbluebutton.core.models.{ Roles, Users2x, @@ -16,19 +19,19 @@ import org.bigbluebutton.core.models.{ object LockSettingsUtil { - private def muteUserInVoiceConf(liveMeeting: LiveMeeting, outGW: OutMsgRouter, vu: VoiceUserState, mute: Boolean): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, vu.intId) - val envelope = BbbCoreEnvelope(MuteUserInVoiceConfSysMsg.NAME, routing) - val header = BbbCoreHeaderWithMeetingId(MuteUserInVoiceConfSysMsg.NAME, liveMeeting.props.meetingProp.intId) - - val body = MuteUserInVoiceConfSysMsgBody(liveMeeting.props.voiceProp.voiceConf, vu.voiceUserId, mute) - val event = MuteUserInVoiceConfSysMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - - outGW.send(msgEvent) + private def muteUserInVoiceConf( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter, + vu: VoiceUserState, mute: Boolean + )(implicit context: ActorContext): Unit = { + VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, mute) } - private def applyMutingOfUsers(disableMic: Boolean, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = { + private def applyMutingOfUsers( + disableMic: Boolean, + liveMeeting: LiveMeeting, + outGW: OutMsgRouter + )(implicit context: ActorContext): Unit = { VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu => Users2x.findWithIntId(liveMeeting.users2x, vu.intId).foreach { user => if (user.role == Roles.VIEWER_ROLE && !vu.listenOnly && user.locked) { @@ -44,12 +47,20 @@ object LockSettingsUtil { } } - def enforceLockSettingsForAllVoiceUsers(liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = { + def enforceLockSettingsForAllVoiceUsers( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter + )(implicit context: ActorContext): Unit = { val permissions = MeetingStatus2x.getPermissions(liveMeeting.status) applyMutingOfUsers(permissions.disableMic, liveMeeting, outGW) } - def enforceLockSettingsForVoiceUser(voiceUser: VoiceUserState, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = { + def enforceLockSettingsForVoiceUser( + voiceUser: VoiceUserState, + liveMeeting: LiveMeeting, + outGW: OutMsgRouter + )(implicit context: ActorContext): Unit = { + val permissions = MeetingStatus2x.getPermissions(liveMeeting.status) if (permissions.disableMic) { Users2x.findWithIntId(liveMeeting.users2x, voiceUser.intId).foreach { user => @@ -65,7 +76,11 @@ object LockSettingsUtil { } } - private def enforceListenOnlyUserIsMuted(intUserId: String, liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = { + private def enforceListenOnlyUserIsMuted( + intUserId: String, + liveMeeting: LiveMeeting, + outGW: OutMsgRouter + )(implicit context: ActorContext): Unit = { val voiceUser = VoiceUsers.findWithIntId(liveMeeting.voiceUsers, intUserId) voiceUser.foreach { vu => // Make sure that listen only user is muted. (ralam dec 6, 2019 diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala index 9a32f958da..21ae848ce1 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala @@ -41,11 +41,16 @@ trait SystemConfiguration { lazy val voiceConfRecordPath = Try(config.getString("voiceConf.recordPath")).getOrElse("/var/freeswitch/meetings") lazy val voiceConfRecordCodec = Try(config.getString("voiceConf.recordCodec")).getOrElse("wav") + lazy val voiceConfRecordEnableFileSplitter = Try(config.getBoolean("voiceConf.recordEnableFileSplitter")).getOrElse(false) + lazy val voiceConfRecordFileSplitterIntervalInMinutes = Try(config.getInt("voiceConf.recordFileSplitterIntervalInMinutes")).getOrElse(15) lazy val checkVoiceRecordingInterval = Try(config.getInt("voiceConf.checkRecordingInterval")).getOrElse(19) lazy val syncVoiceUsersStatusInterval = Try(config.getInt("voiceConf.syncUserStatusInterval")).getOrElse(43) lazy val ejectRogueVoiceUsers = Try(config.getBoolean("voiceConf.ejectRogueVoiceUsers")).getOrElse(true) lazy val dialInApprovalAudioPath = Try(config.getString("voiceConf.dialInApprovalAudioPath")).getOrElse("ivr/ivr-please_hold_while_party_contacted.wav") lazy val toggleListenOnlyAfterMuteTimer = Try(config.getInt("voiceConf.toggleListenOnlyAfterMuteTimer")).getOrElse(4) + lazy val transparentListenOnlyThreshold = Try(config.getInt("voiceConf.transparentListenOnlyThreshold")).getOrElse(0) + lazy val muteOnStartThreshold = Try(config.getInt("voiceConf.muteOnStartThreshold")).getOrElse(0) + lazy val dialInEnforceGuestPolicy = Try(config.getBoolean("voiceConf.dialInEnforceGuestPolicy")).getOrElse(true) lazy val recordingChapterBreakLengthInMinutes = Try(config.getInt("recording.chapterBreakLengthInMinutes")).getOrElse(0) @@ -82,7 +87,7 @@ trait SystemConfiguration { lazy val analyticsIncludeChat = Try(config.getBoolean("analytics.includeChat")).getOrElse(true) lazy val clientSettingsPath = Try(config.getString("client.clientSettingsFilePath")).getOrElse( - "/usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml" + "/var/bigbluebutton/html5-client/private/config/settings.yml" ) lazy val clientSettingsPathOverride = Try(config.getString("client.clientSettingsOverrideFilePath")).getOrElse( "/etc/bigbluebutton/bbb-html5.yml" diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala index 6cc0319310..523262f738 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala @@ -15,6 +15,7 @@ import java.util.concurrent.TimeUnit import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.db.{ DatabaseConnection, MeetingDAO } import org.bigbluebutton.core.domain.MeetingEndReason +import org.bigbluebutton.core.models.Roles import org.bigbluebutton.core.running.RunningMeeting import org.bigbluebutton.core.util.ColorPicker import org.bigbluebutton.core2.RunningMeetings @@ -45,6 +46,8 @@ class BigBlueButtonActor( private val meetings = new RunningMeetings + private var sessionTokens = new collection.immutable.HashMap[String, (String, String)] //sessionToken -> (meetingId, userId) + override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case e: Exception => { val sw: StringWriter = new StringWriter() @@ -55,6 +58,14 @@ class BigBlueButtonActor( } } + object BBBTasksExecutor + context.system.scheduler.schedule( + 1 minute, + 1 minute, + self, + BBBTasksExecutor + ) + override def preStart() { bbbMsgBus.subscribe(self, meetingManagerChannel) DatabaseConnection.initialize() @@ -69,22 +80,61 @@ class BigBlueButtonActor( def receive = { // Internal messages + case BBBTasksExecutor => handleMeetingTasksExecutor() case msg: DestroyMeetingInternalMsg => handleDestroyMeeting(msg) + //Api messages + case msg: GetUserApiMsg => handleGetUserApiMsg(msg, sender) + // 2x messages case msg: BbbCommonEnvCoreMsg => handleBbbCommonEnvCoreMsg(msg) case _ => // do nothing } + private def handleGetUserApiMsg(msg: GetUserApiMsg, actorRef: ActorRef): Unit = { + log.debug("RECEIVED GetUserApiMsg msg {}", msg) + + sessionTokens.get(msg.sessionToken) match { + case Some(sessionTokenInfo) => + RunningMeetings.findWithId(meetings, sessionTokenInfo._1) match { + case Some(m) => + m.actorRef forward (msg) + + case None => + //The meeting is ended, it will return some data just to confirm the session was valid + //The client can request data after the meeting is ended + val userInfos = Map( + "returncode" -> "SUCCESS", + "sessionToken" -> msg.sessionToken, + "meetingID" -> sessionTokenInfo._1, + "internalUserID" -> sessionTokenInfo._2, + "externMeetingID" -> "", + "externUserID" -> "", + "currentlyInMeeting" -> false, + "authToken" -> "", + "role" -> Roles.VIEWER_ROLE, + "guest" -> "false", + "guestStatus" -> "ALLOWED", + "moderator" -> false, + "presenter" -> false, + "hideViewersCursor" -> false, + "hideViewersAnnotation" -> false, + "hideUserList" -> false, + "webcamsOnlyForModerator" -> false + ) + actorRef ! ApiResponseSuccess("Meeting is ended!", UserInfosApiMsg(userInfos)) + } + case None => + actorRef ! ApiResponseFailure("Meeting not found!") + } + } + private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = { msg.core match { case m: CreateMeetingReqMsg => handleCreateMeetingReqMsg(m) case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m) - case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m) - case m: GetRunningMeetingsReqMsg => handleGetRunningMeetingsReqMsg(m) case m: CheckAlivePingSysMsg => handleCheckAlivePingSysMsg(m) - case m: ValidateConnAuthTokenSysMsg => handleValidateConnAuthTokenSysMsg(m) case _: UserGraphqlConnectionEstablishedSysMsg => //Ignore case _: UserGraphqlConnectionClosedSysMsg => //Ignore case _: CheckGraphqlMiddlewareAlivePongSysMsg => //Ignore @@ -92,24 +142,16 @@ class BigBlueButtonActor( } } - def handleValidateConnAuthTokenSysMsg(msg: ValidateConnAuthTokenSysMsg): Unit = { - RunningMeetings.findWithId(meetings, msg.body.meetingId) match { - case Some(meeting) => - meeting.actorRef forward msg - - case None => - val event = MsgBuilder.buildValidateConnAuthTokenSysRespMsg(msg.body.meetingId, msg.body.userId, - false, msg.body.connId, msg.body.app) - outGW.send(event) - } - } - def handleRegisterUserReqMsg(msg: RegisterUserReqMsg): Unit = { log.debug("RECEIVED RegisterUserReqMsg msg {}", msg) for { m <- RunningMeetings.findWithId(meetings, msg.header.meetingId) } yield { log.debug("FORWARDING Register user message") + + //Store sessionTokens and associate them with their respective meetingId + userId owners + sessionTokens += (msg.body.sessionToken -> (msg.body.meetingId, msg.body.intUserId)) + m.actorRef forward (msg) } } @@ -139,32 +181,18 @@ class BigBlueButtonActor( } } - private def handleGetRunningMeetingsReqMsg(msg: GetRunningMeetingsReqMsg): Unit = { - val liveMeetings = RunningMeetings.meetings(meetings) - val meetingIds = liveMeetings.map(m => m.props.meetingProp.intId) - - val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") - val envelope = BbbCoreEnvelope(GetRunningMeetingsRespMsg.NAME, routing) - val header = BbbCoreBaseHeader(GetRunningMeetingsRespMsg.NAME) - - val body = GetRunningMeetingsRespMsgBody(meetingIds) - val event = GetRunningMeetingsRespMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - outGW.send(msgEvent) - } - - private def handleGetAllMeetingsReqMsg(msg: GetAllMeetingsReqMsg): Unit = { - RunningMeetings.meetings(meetings).foreach(m => { - m.actorRef ! msg - }) - } - private def handleCheckAlivePingSysMsg(msg: CheckAlivePingSysMsg): Unit = { val event = MsgBuilder.buildCheckAlivePingSysMsg(msg.body.system, msg.body.bbbWebTimestamp, System.currentTimeMillis()) healthzService.sendPubSubStatusMessage(msg.body.akkaAppsTimestamp, System.currentTimeMillis()) outGW.send(event) } + private def handleMeetingTasksExecutor(): Unit = { + // Delays meeting data for 1 hour post-meeting in case users request info after it ends. + // This routine ensures proper purging if akka-apps restart and the handleDestroyMeeting scheduler does not run. + MeetingDAO.deleteOldMeetings() + } + private def handleDestroyMeeting(msg: DestroyMeetingInternalMsg): Unit = { for { @@ -194,11 +222,15 @@ class BigBlueButtonActor( context.stop(m.actorRef) } - // MeetingDAO.delete(msg.meetingId) - // MeetingDAO.setMeetingEnded(msg.meetingId) - // Removing the meeting is enough, all other tables has "ON DELETE CASCADE" - // UserDAO.softDeleteAllFromMeeting(msg.meetingId) - // MeetingRecordingDAO.updateStopped(msg.meetingId, "") + //Delay removal of session tokens and Graphql data once users might request some info after the meeting is ended + context.system.scheduler.scheduleOnce(Duration.create(60, TimeUnit.MINUTES)) { + log.debug("Removing Graphql data and session tokens. meetingID={}", msg.meetingId) + + sessionTokens = sessionTokens.filter(sessionTokenInfo => sessionTokenInfo._2._1 != msg.meetingId) + + //In Db, Removing the meeting is enough, all other tables has "ON DELETE CASCADE" + MeetingDAO.delete(msg.meetingId) + } //Remove ColorPicker idx of the meeting ColorPicker.reset(m.props.meetingProp.intId) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala index f058250478..be2d3d72d4 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala @@ -25,16 +25,7 @@ case class MonitorNumberOfUsersInternalMsg(meetingID: String) extends InMessage * Audit message sent to meeting to trigger updating clients of meeting time remaining. * @param meetingId */ -case class SendTimeRemainingAuditInternalMsg(meetingId: String, timeUpdatedInMinutes: Int) extends InMessage - -/** - * Parent message sent to breakout rooms to trigger updating clients of meeting time remaining. - * @param meetingId - * @param timeLeftInSec - */ -case class SendBreakoutTimeRemainingInternalMsg(meetingId: String, timeLeftInSec: Long, timeUpdatedInMinutes: Int) extends InMessage - -case class SendRecordingTimerInternalMsg(meetingId: String) extends InMessage +case class MonitorGuestWaitPresenceInternalMsg(meetingId: String) extends InMessage case class ExtendMeetingDuration(meetingId: String, userId: String) extends InMessage case class DestroyMeetingInternalMsg(meetingId: String) extends InMessage @@ -130,4 +121,14 @@ case class UserClosedAllGraphqlConnectionsInternalMsg(userId: String) extends In * Sent by GraphqlActionsActor to inform MeetingActor that user came back from disconnection * @param userId */ -case class UserEstablishedGraphqlConnectionInternalMsg(userId: String) extends InMessage +case class UserEstablishedGraphqlConnectionInternalMsg(userId: String, clientType: String, isMobile: Boolean) extends InMessage + +/** + * API endpoint /userInfo to provide User Session Variables messages + */ +case class GetUserApiMsg(sessionToken: String) +case class UserInfosApiMsg(infos: Map[String, Any]) + +trait ApiResponse +case class ApiResponseSuccess(msg: String, any: Any = null) extends ApiResponse +case class ApiResponseFailure(msg: String, any: Any = null) extends ApiResponse \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutModel.scala index cf83653d87..bba8d27930 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/BreakoutModel.scala @@ -18,8 +18,11 @@ object BreakoutModel { captureSlides: Boolean, captureNotesFilename: String, captureSlidesFilename: String, + allPages: Boolean, + presId: String, ): BreakoutRoom2x = { - new BreakoutRoom2x(id, externalId, name, parentId, sequence, shortName, isDefaultName, freeJoin, voiceConf, assignedUsers, Vector(), Vector(), None, false, captureNotes, captureSlides, captureNotesFilename, captureSlidesFilename) + new BreakoutRoom2x(id, externalId, name, parentId, sequence, shortName, isDefaultName, freeJoin, voiceConf, assignedUsers, Vector(), Vector(), None, false, + captureNotes, captureSlides, captureNotesFilename, captureSlidesFilename, allPages, presId) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/CaptionModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/CaptionModel.scala index 6e074c7d11..b8edeb1ada 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/CaptionModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/CaptionModel.scala @@ -20,32 +20,6 @@ class CaptionModel { return None } - def updateTranscriptOwner(name: String, locale: String, ownerId: String): Map[String, TranscriptVO] = { - var updatedTranscripts = new HashMap[String, TranscriptVO] - - // clear owner from previous locale - if (ownerId.length > 0) { - findTranscriptByOwnerId(ownerId).foreach(t => { - val oldTranscript = t._2.copy(ownerId = "") - - transcripts += t._1 -> oldTranscript - updatedTranscripts += t._1 -> oldTranscript - }) - } - // change the owner if it does exist - if (transcripts contains name) { - val newTranscript = transcripts(name).copy(ownerId = ownerId) - - transcripts += name -> newTranscript - updatedTranscripts += name -> newTranscript - } else { // create the locale if it doesn't exist - val addedTranscript = createTranscript(name, locale, ownerId) - updatedTranscripts += name -> addedTranscript - } - - updatedTranscripts - } - def getHistory(): Map[String, TranscriptVO] = { transcripts } @@ -97,20 +71,6 @@ class CaptionModel { locale } - def checkCaptionOwnerLogOut(userId: String): Option[(String, TranscriptVO)] = { - var rtnTranscript: Option[(String, TranscriptVO)] = None - - if (userId.length > 0) { - findTranscriptByOwnerId(userId).foreach(t => { - val oldTranscript = t._2.copy(ownerId = "") - - transcripts += t._1 -> oldTranscript - rtnTranscript = Some((t._1, oldTranscript)) - }) - } - rtnTranscript - } - def isUserCaptionOwner(userId: String, name: String): Boolean = { var isOwner: Boolean = false; diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/GuestsApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/GuestsApp.scala index 565844f6b2..31fd1863fa 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/GuestsApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/GuestsApp.scala @@ -5,7 +5,6 @@ import org.bigbluebutton.core2.message.handlers.guests._ trait GuestsApp extends GetGuestsWaitingApprovalReqMsgHdlr with GuestsWaitingApprovedMsgHdlr - with GuestWaitingLeftMsgHdlr with UpdatePositionInWaitingQueueReqMsgHdlr with SetGuestPolicyMsgHdlr with SetGuestLobbyMessageMsgHdlr diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermissionCheck.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermissionCheck.scala index 9cf22067a1..270975fd0d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermissionCheck.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PermissionCheck.scala @@ -88,9 +88,6 @@ object PermissionCheck extends SystemConfiguration { UsersApp.ejectUserFromMeeting(outGW, liveMeeting, userId, ejectedBy, reason, EjectReasonCode.PERMISSION_FAILED, ban = false) - // send a system message to force disconnection - Sender.sendDisconnectClientSysMsg(meetingId, userId, ejectedBy, reason, outGW) - // Force reconnection with graphql to refresh permissions for { regUser <- RegisteredUsers.findWithUserId(userId, liveMeeting.registeredUsers) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/TimerModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/TimerModel.scala index 9924648a9e..95bec8147e 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/TimerModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/TimerModel.scala @@ -6,7 +6,7 @@ object TimerModel { stopwatch: Boolean = true, time: Int = 0, accumulated: Int = 0, - track: String = "", + track: String = "noTrack", ): Unit = { model.stopwatch = stopwatch model.time = time @@ -17,7 +17,6 @@ object TimerModel { def reset(model: TimerModel) : Unit = { model.accumulated = 0 model.startedAt = if (model.running) System.currentTimeMillis() else 0 - model.endedAt = 0 } def setIsActive(model: TimerModel, active: Boolean): Unit = { @@ -45,18 +44,39 @@ object TimerModel { } def setRunning(model: TimerModel, running: Boolean): Unit = { + resetTimerIfFinished(model) - //If it is running and will stop, calculate new Accumulated - if(getRunning(model) && !running) { - val now = System.currentTimeMillis() + val now = System.currentTimeMillis() + + // If the timer is running and will stop, update accumulated time + if (isRunning(model) && !running) { val accumulated = getAccumulated(model) + Math.abs(now - getStartedAt(model)).toInt - this.setAccumulated(model, accumulated) + setAccumulated(model, accumulated) } + // If the timer is not running and will start, set the start time + if (!isRunning(model) && running) { + setStartedAt(model, now) + } + + // Update the running status of the model model.running = running } - def getRunning(model: TimerModel): Boolean = { + def resetTimerIfFinished(model: TimerModel) = { + // If the timer is finished, reset the accumulated time and start time if running + if (isRunning(model) + && !isStopwatch(model) + && (model.startedAt + (model.time - model.accumulated)) < System.currentTimeMillis()) { + model.running = false + reset(model) + true + } else { + false + } + } + + def isRunning(model: TimerModel): Boolean = { model.running } @@ -64,7 +84,7 @@ object TimerModel { model.stopwatch = stopwatch } - def getStopwatch(model: TimerModel): Boolean = { + def isStopwatch(model: TimerModel): Boolean = { model.stopwatch } @@ -83,23 +103,14 @@ object TimerModel { def getTime(model: TimerModel): Int = { model.time } - - def setEndedAt(model: TimerModel, timestamp: Long): Unit = { - model.endedAt = timestamp - } - - def getEndedAt(model: TimerModel): Long = { - model.endedAt - } } class TimerModel { private var startedAt: Long = 0 - private var endedAt: Long = 0 private var accumulated: Int = 0 private var running: Boolean = false private var time: Int = 0 private var stopwatch: Boolean = true - private var track: String = "" + private var track: String = "noTrack" private var isActive: Boolean = false } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala index b96ed125d9..6a32281844 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala @@ -54,11 +54,21 @@ class WhiteboardModel extends SystemConfiguration { for (annotation <- annotations) { val oldAnnotation = wb.annotationsMap.get(annotation.id) - if (!oldAnnotation.isEmpty) { + if (oldAnnotation.isDefined) { val hasPermission = isPresenter || isModerator || oldAnnotation.get.userId == userId if (hasPermission) { - // Merge old and new annotation properties - val mergedAnnotationInfo = deepMerge(oldAnnotation.get.annotationInfo, annotation.annotationInfo) + // Determine if the annotation is a line shape + val isLineShape = annotation.annotationInfo.get("type").contains("line") + + // Merge old and new annotation properties with special handling for line shape + val mergedAnnotationInfo = if (isLineShape) { + val newProps = annotation.annotationInfo.get("props").asInstanceOf[Option[Map[String, Any]]].getOrElse(Map.empty) + val oldProps = oldAnnotation.get.annotationInfo.get("props").asInstanceOf[Option[Map[String, Any]]].getOrElse(Map.empty) + val updatedProps = overwriteLineShapeHandles(oldProps, newProps) + annotation.annotationInfo + ("props" -> updatedProps) + } else { + deepMerge(oldAnnotation.get.annotationInfo, annotation.annotationInfo) + } // Apply cleaning if it's an arrow annotation val finalAnnotationInfo = if (annotation.annotationInfo.get("type").contains("arrow")) { @@ -90,6 +100,15 @@ class WhiteboardModel extends SystemConfiguration { annotationsAdded } + private def overwriteLineShapeHandles(oldProps: Map[String, Any], newProps: Map[String, Any]): Map[String, Any] = { + val newHandles = newProps.get("handles") + val updatedProps = oldProps ++ newProps.filter { + case ("handles", _) => false // Remove the old handles + case _ => true + } + updatedProps ++ newHandles.map("handles" -> _) + } + private def cleanArrowAnnotationProps(annotationInfo: Map[String, _]): Map[String, _] = { annotationInfo.get("props") match { case Some(props: Map[String, _]) => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/audiocaptions/UpdateTranscriptPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/audiocaptions/UpdateTranscriptPubMsgHdlr.scala index 4e96201fef..a668726f05 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/audiocaptions/UpdateTranscriptPubMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/audiocaptions/UpdateTranscriptPubMsgHdlr.scala @@ -4,7 +4,7 @@ import org.bigbluebutton.ClientSettings.getConfigPropertyValueByPathAsStringOrEl import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.bus.MessageBus import org.bigbluebutton.core.db.CaptionDAO -import org.bigbluebutton.core.models.{AudioCaptions, UserState, Users2x} +import org.bigbluebutton.core.models.{AudioCaptions, UserState, Pads, Users2x} import org.bigbluebutton.core.running.LiveMeeting import java.time.LocalDateTime import java.time.format.DateTimeFormatter @@ -26,12 +26,12 @@ trait UpdateTranscriptPubMsgHdlr { bus.outGW.send(msgEvent) } - def sendPadUpdatePubMsg(userId: String, defaultPad: String, text: String, transcript: Boolean): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, "nodeJSapp") - val envelope = BbbCoreEnvelope(PadUpdatePubMsg.NAME, routing) - val header = BbbClientMsgHeader(PadUpdatePubMsg.NAME, meetingId, userId) - val body = PadUpdatePubMsgBody(defaultPad, text, transcript) - val event = PadUpdatePubMsg(header, body) + def sendPadUpdateCmdMsg(groupId: String, defaultPad: String, text: String, transcript: Boolean): Unit = { + val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") + val envelope = BbbCoreEnvelope(PadUpdateCmdMsg.NAME, routing) + val header = BbbCoreHeaderWithMeetingId(PadUpdateCmdMsg.NAME, liveMeeting.props.meetingProp.intId) + val body = PadUpdateCmdMsgBody(groupId, defaultPad, text) + val event = PadUpdateCmdMsg(header, body) val msgEvent = BbbCommonEnvCoreMsg(envelope, event) bus.outGW.send(msgEvent) @@ -82,7 +82,7 @@ trait UpdateTranscriptPubMsgHdlr { for { u <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId) } yield { - CaptionDAO.insertOrUpdateAudioCaption(msg.body.transcriptId, meetingId, msg.header.userId, transcript, u.speechLocale) + CaptionDAO.insertOrUpdateCaption(msg.body.transcriptId, meetingId, msg.header.userId, transcript, u.speechLocale) } broadcastEvent( @@ -111,7 +111,10 @@ trait UpdateTranscriptPubMsgHdlr { alternativeValue = "" ) - sendPadUpdatePubMsg(msg.header.userId, defaultPad, userSpoke, transcript = true) + Pads.getGroup(liveMeeting.pads, defaultPad) match { + case Some(group) => sendPadUpdateCmdMsg(group.groupId, defaultPad, userSpoke, transcript = true) + case _ => + } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutApp2x.scala index 9a02c67527..27c048fc9d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutApp2x.scala @@ -16,6 +16,7 @@ trait BreakoutApp2x extends BreakoutRoomCreatedMsgHdlr with SendMessageToAllBreakoutRoomsMsgHdlr with SendMessageToBreakoutRoomInternalMsgHdlr with RequestBreakoutJoinURLReqMsgHdlr + with SetBreakoutRoomInviteDismissedReqMsgHdlr with SendBreakoutUsersUpdateMsgHdlr with TransferUserToMeetingRequestHdlr with EndBreakoutRoomInternalMsgHdlr diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomUsersUpdateMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomUsersUpdateMsgHdlr.scala index 6c9d4e88e5..0fecbb1834 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomUsersUpdateMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutRoomUsersUpdateMsgHdlr.scala @@ -1,9 +1,8 @@ package org.bigbluebutton.core.apps.breakout -import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.api.BreakoutRoomUsersUpdateInternalMsg import org.bigbluebutton.core.db.{ BreakoutRoomUserDAO, UserBreakoutRoomDAO } -import org.bigbluebutton.core.domain.{ BreakoutRoom2x, MeetingState2x } +import org.bigbluebutton.core.domain.MeetingState2x import org.bigbluebutton.core.models.{ RegisteredUsers, Users2x } import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter } @@ -14,24 +13,11 @@ trait BreakoutRoomUsersUpdateMsgHdlr { def handleBreakoutRoomUsersUpdateInternalMsg(msg: BreakoutRoomUsersUpdateInternalMsg, state: MeetingState2x): MeetingState2x = { - def broadcastEvent(room: BreakoutRoom2x): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, "not-used") - val envelope = BbbCoreEnvelope(UpdateBreakoutUsersEvtMsg.NAME, routing) - val header = BbbClientMsgHeader(UpdateBreakoutUsersEvtMsg.NAME, props.meetingProp.intId, "not-used") - - val users = room.users.map(u => BreakoutUserVO(u.id, u.name)) - val body = UpdateBreakoutUsersEvtMsgBody(props.meetingProp.intId, msg.breakoutId, users) - val event = UpdateBreakoutUsersEvtMsg(header, body) - BbbCommonEnvCoreMsg(envelope, event) - } - val breakoutModel = for { model <- state.breakout room <- model.find(msg.breakoutId) } yield { val updatedRoom = room.copy(users = msg.users, voiceUsers = msg.voiceUsers) - val msgEvent = broadcastEvent(updatedRoom) - outGW.send(msgEvent) //Update user lastActivityTime in parent room (to avoid be ejected while is in Breakout room) for { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/ChangeUserBreakoutReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/ChangeUserBreakoutReqMsgHdlr.scala index cccc23934d..46dd23d5f7 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/ChangeUserBreakoutReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/ChangeUserBreakoutReqMsgHdlr.scala @@ -38,6 +38,9 @@ trait ChangeUserBreakoutReqMsgHdlr extends RightsManagementTrait { }) } + val isSameRoom = msg.body.fromBreakoutId == msg.body.toBreakoutId + val removePreviousRoomFromDb = !breakoutModel.rooms.exists(r => r._2.freeJoin) && !isSameRoom + //Get join URL for room To val redirectToHtml5JoinURL = ( for { @@ -46,7 +49,6 @@ trait ChangeUserBreakoutReqMsgHdlr extends RightsManagementTrait { } yield redirectToHtml5JoinURL ).getOrElse("") - BreakoutHdlrHelpers.sendChangeUserBreakoutMsg( outGW, meetingId, @@ -57,8 +59,13 @@ trait ChangeUserBreakoutReqMsgHdlr extends RightsManagementTrait { ) //Update database - BreakoutRoomUserDAO.updateRoomChanged(meetingId, msg.body.userId, msg.body.fromBreakoutId, msg.body.toBreakoutId, redirectToHtml5JoinURL) - + BreakoutRoomUserDAO.updateRoomChanged( + meetingId, + msg.body.userId, + msg.body.fromBreakoutId, + msg.body.toBreakoutId, + redirectToHtml5JoinURL, + removePreviousRoomFromDb) //Send notification to moved User for { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala index f6f8a2e6cd..5401ece7ba 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/CreateBreakoutRoomsCmdMsgHdlr.scala @@ -55,26 +55,30 @@ trait CreateBreakoutRoomsCmdMsgHdlr extends RightsManagementTrait { } def processRequest(msg: CreateBreakoutRoomsCmdMsg, state: MeetingState2x): MeetingState2x = { - - val presId = getPresentationId(state) - val presSlide = getPresentationSlide(state) + val presId = getPresentationId(state) // The current presentation + val presSlide = getPresentationSlide(state) // The current slide val parentId = liveMeeting.props.meetingProp.intId var rooms = new collection.immutable.HashMap[String, BreakoutRoom2x] var i = 0 for (room <- msg.body.rooms) { + val roomPresId = if (room.presId.isEmpty) presId else room.presId; + i += 1 val (internalId, externalId) = BreakoutRoomsUtil.createMeetingIds(liveMeeting.props.meetingProp.intId, i) val voiceConf = BreakoutRoomsUtil.createVoiceConfId(liveMeeting.props.voiceProp.voiceConf, i) val breakout = BreakoutModel.create(parentId, internalId, externalId, room.name, room.sequence, room.shortName, room.isDefaultName, room.freeJoin, voiceConf, room.users, msg.body.captureNotes, - msg.body.captureSlides, room.captureNotesFilename, room.captureSlidesFilename) + msg.body.captureSlides, room.captureNotesFilename, room.captureSlidesFilename, + room.allPages, roomPresId) rooms = rooms + (breakout.id -> breakout) } for (breakout <- rooms.values.toVector) { + val roomSlides = if (breakout.allPages) -1 else presSlide; + val roomDetail = new BreakoutRoomDetail( breakout.id, breakout.name, liveMeeting.props.meetingProp.intId, @@ -87,7 +91,9 @@ trait CreateBreakoutRoomsCmdMsgHdlr extends RightsManagementTrait { msg.body.durationInMinutes, liveMeeting.props.password.moderatorPass, liveMeeting.props.password.viewerPass, - presId, presSlide, msg.body.record, + breakout.presId, + roomSlides, + msg.body.record, liveMeeting.props.breakoutProps.privateChatEnabled, breakout.captureNotes, breakout.captureSlides, diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EjectUserFromBreakoutInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EjectUserFromBreakoutInternalMsgHdlr.scala index 27cff5d55b..f3a8a52d74 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EjectUserFromBreakoutInternalMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EjectUserFromBreakoutInternalMsgHdlr.scala @@ -32,9 +32,6 @@ trait EjectUserFromBreakoutInternalMsgHdlr { //TODO inform reason UserDAO.softDelete(registeredUser.meetingId, registeredUser.id) - // send a system message to force disconnection - Sender.sendDisconnectClientSysMsg(msg.breakoutId, registeredUser.id, msg.ejectedBy, msg.reasonCode, outGW) - // Force reconnection with graphql to refresh permissions Sender.sendForceUserGraphqlReconnectionSysMsg(liveMeeting.props.meetingProp.intId, registeredUser.id, registeredUser.sessionToken, msg.reasonCode, outGW) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndBreakoutRoomInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndBreakoutRoomInternalMsgHdlr.scala index 7a29463a7d..63e76bd5e7 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndBreakoutRoomInternalMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/EndBreakoutRoomInternalMsgHdlr.scala @@ -1,10 +1,11 @@ package org.bigbluebutton.core.apps.breakout -import org.bigbluebutton.common2.msgs.{ BbbClientMsgHeader, BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, ExportJob, MessageTypes, PresentationConversionUpdateEvtMsg, PresentationConversionUpdateEvtMsgBody, PresentationConversionUpdateSysPubMsg, PresentationUploadTokenSysPubMsg, PresentationUploadTokenSysPubMsgBody, Routing, StoreExportJobInRedisSysMsg, StoreExportJobInRedisSysMsgBody } +import org.bigbluebutton.common2.msgs.{ BbbClientMsgHeader, BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, ExportJob, MessageTypes, PresentationConversionUpdateEvtMsg, PresentationConversionUpdateEvtMsgBody, PresentationConversionUpdateSysPubMsg, PresentationPageForExport, PresentationUploadTokenSysPubMsg, PresentationUploadTokenSysPubMsgBody, Routing, StoreExportJobInRedisSysMsg, StoreExportJobInRedisSysMsgBody, StoredAnnotations } import org.bigbluebutton.core.api.{ CapturePresentationReqInternalMsg, EndBreakoutRoomInternalMsg } import org.bigbluebutton.core.apps.presentationpod.PresentationPodsApp import org.bigbluebutton.core.bus.{ BigBlueButtonEvent, InternalEventBus } -import org.bigbluebutton.core.models.Pads +import org.bigbluebutton.core.db.{ PresPresentationDAO } +import org.bigbluebutton.core.models.{ Pads, PresentationInPod, PresentationPage, PresentationPod } import org.bigbluebutton.core.running.{ BaseMeetingActor, HandlerHelpers, LiveMeeting, OutMsgRouter } trait EndBreakoutRoomInternalMsgHdlr extends HandlerHelpers { @@ -22,34 +23,46 @@ trait EndBreakoutRoomInternalMsgHdlr extends HandlerHelpers { } if (liveMeeting.props.breakoutProps.captureNotes) { - for { - group <- Pads.getGroup(liveMeeting.pads, "notes") - } yield { - val filename = liveMeeting.props.breakoutProps.captureNotesFilename - val userId: String = "system" - val jobId: String = s"${msg.breakoutId}-notes" // Used as the temporaryPresentationId upon upload - val presentationId = PresentationPodsApp.generatePresentationId(filename) - - if (group.rev > 0) { - //Request upload of the sharedNotes of breakoutRoom - val presentationUploadToken: String = PresentationPodsApp.generateToken("DEFAULT_PRESENTATION_POD", userId) - outGW.send(buildPresentationUploadTokenSysPubMsg(msg.parentId, userId, presentationUploadToken, filename, presentationId)) - - val exportJob = ExportJob(jobId, "PadCaptureJob", filename, filename, group.padId, "", allPages = true, List(), msg.parentId, presentationUploadToken) - val job = buildStoreExportJobInRedisSysMsg(exportJob, liveMeeting) - outGW.send(job) - } else { - // Notify that no content is available - val event = buildPresentationConversionUpdateEvtMsg(msg.parentId, presentationId, filename, jobId) - outGW.send(event) - } - } + handleCaptureNotes(msg) } log.info("Breakout room {} ended by parent meeting {}.", msg.breakoutId, msg.parentId) sendEndMeetingDueToExpiry(msg.reason, eventBus, outGW, liveMeeting, "system") } + def handleCaptureNotes(msg: EndBreakoutRoomInternalMsg) { + for { + group <- Pads.getGroup(liveMeeting.pads, "notes") + } yield { + val filename = liveMeeting.props.breakoutProps.captureNotesFilename + val userId: String = "system" + val jobId: String = s"${msg.breakoutId}-notes" // Used as the temporaryPresentationId upon upload + val presentationId = PresentationPodsApp.generatePresentationId(filename) + + var pres = new PresentationInPod(presentationId, default = false, current = false, name = filename, + pages = Map.empty, downloadable = false, downloadFileExtension = "", removable = true, filenameConverted = filename, + uploadCompleted = false, numPages = 0, errorMsgKey = "", errorDetails = Map.empty) + + if (group.rev > 0) { + //Request upload of the sharedNotes of breakoutRoom + val presentationUploadToken: String = PresentationPodsApp.generateToken("DEFAULT_PRESENTATION_POD", userId) + outGW.send(buildPresentationUploadTokenSysPubMsg(msg.parentId, userId, presentationUploadToken, filename, presentationId)) + + val exportJob = ExportJob(jobId, "PadCaptureJob", filename, filename, group.padId, "", allPages = true, List(), msg.parentId, presentationUploadToken) + val job = buildStoreExportJobInRedisSysMsg(exportJob, liveMeeting) + outGW.send(job) + } else { + pres = pres.copy(errorMsgKey = "204") + + val event = buildPresentationConversionUpdateEvtMsg(msg.parentId, presentationId, filename, jobId) + outGW.send(event) + } + + PresPresentationDAO.updateConversionStarted(msg.parentId, pres) + + } + } + def buildStoreExportJobInRedisSysMsg(exportJob: ExportJob, liveMeeting: LiveMeeting): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") val envelope = BbbCoreEnvelope(StoreExportJobInRedisSysMsg.NAME, routing) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala deleted file mode 100755 index e957a73bf3..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SendBreakoutTimeRemainingInternalMsgHdlr.scala +++ /dev/null @@ -1,15 +0,0 @@ -package org.bigbluebutton.core.apps.breakout - -import org.bigbluebutton.core.api.SendBreakoutTimeRemainingInternalMsg -import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } -import org.bigbluebutton.core2.message.senders.MsgBuilder - -trait SendBreakoutTimeRemainingInternalMsgHdlr { - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleSendBreakoutTimeRemainingInternalMsg(msg: SendBreakoutTimeRemainingInternalMsg): Unit = { - val event = MsgBuilder.buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, msg.timeLeftInSec.toInt, msg.timeUpdatedInMinutes) - outGW.send(event) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SetBreakoutRoomInviteDismissedReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SetBreakoutRoomInviteDismissedReqMsgHdlr.scala new file mode 100755 index 0000000000..92406fcad1 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/SetBreakoutRoomInviteDismissedReqMsgHdlr.scala @@ -0,0 +1,22 @@ +package org.bigbluebutton.core.apps.breakout + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } +import org.bigbluebutton.core.db.BreakoutRoomUserDAO +import org.bigbluebutton.core.domain.MeetingState2x +import org.bigbluebutton.core.models.{ Roles, Users2x } +import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter } + +trait SetBreakoutRoomInviteDismissedReqMsgHdlr extends RightsManagementTrait { + this: MeetingActor => + + val outGW: OutMsgRouter + + def handleSetBreakoutRoomInviteDismissedReqMsg(msg: SetBreakoutRoomInviteDismissedReqMsg) = { + for { + requesterUser <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId) + } yield { + BreakoutRoomUserDAO.updateInviteDismissedAt(requesterUser.meetingId, requesterUser.intId) + } + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/UpdateBreakoutRoomsTimeMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/UpdateBreakoutRoomsTimeMsgHdlr.scala index 86cb9ad73e..1bf2ca4c3d 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/UpdateBreakoutRoomsTimeMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/UpdateBreakoutRoomsTimeMsgHdlr.scala @@ -1,7 +1,7 @@ package org.bigbluebutton.core.apps.breakout import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.api.{ SendTimeRemainingAuditInternalMsg, UpdateBreakoutRoomTimeInternalMsg } +import org.bigbluebutton.core.api.UpdateBreakoutRoomTimeInternalMsg import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } import org.bigbluebutton.core.bus.BigBlueButtonEvent import org.bigbluebutton.core.db.{ BreakoutRoomDAO, MeetingDAO, NotificationDAO } @@ -88,9 +88,6 @@ trait UpdateBreakoutRoomsTimeMsgHdlr extends RightsManagementTrait { val event = buildUpdateBreakoutRoomsTimeEvtMsg(msg.body.timeInMinutes) outGW.send(event) - //Force Update time remaining in the clients - eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendTimeRemainingAuditInternalMsg(props.meetingProp.intId, msg.body.timeInMinutes))) - updatedModel match { case Some(model) => { state.update(Some(model)) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/caption/CaptionApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/caption/CaptionApp2x.scala index 43e4041be7..79ca361d4a 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/caption/CaptionApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/caption/CaptionApp2x.scala @@ -6,7 +6,7 @@ import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.bus.MessageBus import org.bigbluebutton.core.running.LiveMeeting import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } -import org.bigbluebutton.core.db.{ CaptionLocaleDAO, CaptionTypes } +import org.bigbluebutton.core.db.{ CaptionDAO, CaptionLocaleDAO, CaptionTypes } class CaptionApp2x(implicit val context: ActorContext) extends RightsManagementTrait { val log = Logging(context.system, getClass) @@ -15,18 +15,10 @@ class CaptionApp2x(implicit val context: ActorContext) extends RightsManagementT liveMeeting.captionModel.getHistory() } - def updateCaptionOwner(liveMeeting: LiveMeeting, name: String, locale: String, userId: String): Map[String, TranscriptVO] = { - liveMeeting.captionModel.updateTranscriptOwner(name, locale, userId) - } - def editCaptionHistory(liveMeeting: LiveMeeting, userId: String, startIndex: Integer, endIndex: Integer, name: String, text: String): Boolean = { liveMeeting.captionModel.editHistory(userId, startIndex, endIndex, name, text) } - def checkCaptionOwnerLogOut(liveMeeting: LiveMeeting, userId: String): Option[(String, TranscriptVO)] = { - liveMeeting.captionModel.checkCaptionOwnerLogOut(userId) - } - def isUserCaptionOwner(liveMeeting: LiveMeeting, userId: String, name: String): Boolean = { liveMeeting.captionModel.isUserCaptionOwner(userId, name) } @@ -59,7 +51,23 @@ class CaptionApp2x(implicit val context: ActorContext) extends RightsManagementT } } } + def handle(msg: CaptionSubmitTranscriptPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { + val meetingId = liveMeeting.props.meetingProp.intId + def broadcastSuccessEvent(transcriptId: String, transcript: String, locale: String): Unit = { + val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId) + val envelope = BbbCoreEnvelope(CaptionSubmitTranscriptEvtMsg.NAME, routing) + val header = BbbClientMsgHeader(CaptionSubmitTranscriptEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId) + val body = CaptionSubmitTranscriptEvtMsgBody(transcriptId, transcript, locale, msg.body.captionType) + val event = CaptionSubmitTranscriptEvtMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, event) + bus.outGW.send(msgEvent) + } + CaptionDAO.insertOrUpdateCaption(msg.body.transcriptId, meetingId, msg.header.userId, + msg.body.transcript, msg.body.locale, msg.body.captionType) + + broadcastSuccessEvent(msg.body.transcriptId, msg.body.transcript, msg.body.locale) + } def handle(msg: SendCaptionHistoryReqMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { def broadcastEvent(msg: SendCaptionHistoryReqMsg, history: Map[String, TranscriptVO]): Unit = { val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, msg.header.userId) @@ -75,46 +83,25 @@ class CaptionApp2x(implicit val context: ActorContext) extends RightsManagementT broadcastEvent(msg, getCaptionHistory(liveMeeting)) } - def handle(msg: UpdateCaptionOwnerPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { - def broadcastUpdateCaptionOwnerEvent(name: String, locale: String, newOwnerId: String): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, newOwnerId) - val envelope = BbbCoreEnvelope(UpdateCaptionOwnerEvtMsg.NAME, routing) - val header = BbbClientMsgHeader(UpdateCaptionOwnerEvtMsg.NAME, liveMeeting.props.meetingProp.intId, newOwnerId) + def handle(msg: AddCaptionLocalePubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { + def broadcastAddCaptionLocaleEvent(locale: String, userId: String): Unit = { + val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, userId) + val envelope = BbbCoreEnvelope(AddCaptionLocaleEvtMsg.NAME, routing) + val header = BbbClientMsgHeader(AddCaptionLocaleEvtMsg.NAME, liveMeeting.props.meetingProp.intId, userId) - val body = UpdateCaptionOwnerEvtMsgBody(name, locale, newOwnerId) - val event = UpdateCaptionOwnerEvtMsg(header, body) + val body = AddCaptionLocaleEvtMsgBody(locale) + val event = AddCaptionLocaleEvtMsg(header, body) val msgEvent = BbbCommonEnvCoreMsg(envelope, event) bus.outGW.send(msgEvent) - CaptionLocaleDAO.insertOrUpdateCaptionLocale(liveMeeting.props.meetingProp.intId, locale, CaptionTypes.TYPED, newOwnerId) + CaptionLocaleDAO.insertOrUpdateCaptionLocale(liveMeeting.props.meetingProp.intId, locale, CaptionTypes.TYPED, userId) } if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) { val meetingId = liveMeeting.props.meetingProp.intId - val reason = "No permission to change caption owners." + val reason = "No permission to add caption locale." PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting) } else { - updateCaptionOwner(liveMeeting, msg.body.name, msg.body.locale, msg.body.ownerId).foreach(f => { - broadcastUpdateCaptionOwnerEvent(f._1, f._2.locale, f._2.ownerId) - }) - } - } - - def handleUserLeavingMsg(userId: String, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { - def broadcastUpdateCaptionOwnerEvent(name: String, locale: String, newOwnerId: String): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, newOwnerId) - val envelope = BbbCoreEnvelope(UpdateCaptionOwnerEvtMsg.NAME, routing) - val header = BbbClientMsgHeader(UpdateCaptionOwnerEvtMsg.NAME, liveMeeting.props.meetingProp.intId, newOwnerId) - - val body = UpdateCaptionOwnerEvtMsgBody(name, locale, newOwnerId) - val event = UpdateCaptionOwnerEvtMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - bus.outGW.send(msgEvent) - } - - for { - transcriptInfo <- checkCaptionOwnerLogOut(liveMeeting, userId) - } yield { - broadcastUpdateCaptionOwnerEvent(transcriptInfo._1, transcriptInfo._2.locale, transcriptInfo._2.ownerId) + broadcastAddCaptionLocaleEvent(msg.body.locale, msg.header.userId) } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala index b483dbdf63..5c0eafd920 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/CreateGroupChatReqMsgHdlr.scala @@ -53,7 +53,7 @@ trait CreateGroupChatReqMsgHdlr extends SystemConfiguration { } else { GroupChatApp.getGroupChatOfUsers(msg.header.userId, msg.body.users, state) match { case Some(groupChat) => - ChatUserDAO.updateChatVisible(msg.header.meetingId, groupChat.id, msg.header.userId) + ChatUserDAO.updateChatVisible(msg.header.meetingId, groupChat.id, msg.header.userId, visible = true) state case None => val newState = for { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChat.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChat.scala index 82a86900b7..15a7f0de53 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChat.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChat.scala @@ -20,10 +20,10 @@ object GroupChatApp { GroupChatFactory.create(gcId, access, createBy, users, msgs) } - def toGroupChatMessage(sender: GroupChatUser, msg: GroupChatMsgFromUser, emphasizedText: Boolean): GroupChatMessage = { + def toGroupChatMessage(sender: GroupChatUser, msg: GroupChatMsgFromUser, emphasizedText: Boolean, metadata: Map[String, Any] = Map.empty): GroupChatMessage = { val now = System.currentTimeMillis() val id = GroupChatFactory.genId() - GroupChatMessage(id, now, msg.correlationId, now, now, sender, emphasizedText, msg.message) + GroupChatMessage(id, now, msg.correlationId, now, now, sender, emphasizedText, msg.message, metadata) } def toMessageToUser(msg: GroupChatMessage): GroupChatMsgToUser = { @@ -36,7 +36,7 @@ object GroupChatApp { if (msg.sender.id == SystemUser.ID) { ChatMessageDAO.insertSystemMsg(meetingId, chat.id, msg.message, messageType, Map(), msg.sender.name) } else { - ChatMessageDAO.insert(meetingId, chat.id, msg) + ChatMessageDAO.insert(meetingId, chat.id, msg, messageType) } val c = chat.add(msg) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChatHdlrs.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChatHdlrs.scala index 6b815f90a8..65449c5cd9 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChatHdlrs.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/GroupChatHdlrs.scala @@ -9,7 +9,9 @@ class GroupChatHdlrs(implicit val context: ActorContext) with GetGroupChatMsgsReqMsgHdlr with GetGroupChatsReqMsgHdlr with SendGroupChatMessageMsgHdlr - with SyncGetGroupChatsInfoMsgHdlr { + with SendGroupChatMessageFromApiSysPubMsgHdlr + with SetGroupChatVisibleReqMsgHdlr + with SetGroupChatLastSeenReqMsgHdlr { val log = Logging(context.system, getClass) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageFromApiSysPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageFromApiSysPubMsgHdlr.scala new file mode 100755 index 0000000000..8334377e81 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageFromApiSysPubMsgHdlr.scala @@ -0,0 +1,46 @@ +package org.bigbluebutton.core.apps.groupchats + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.bus.MessageBus +import org.bigbluebutton.core.domain.MeetingState2x +import org.bigbluebutton.core.models.SystemUser +import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting } + +trait SendGroupChatMessageFromApiSysPubMsgHdlr extends HandlerHelpers { + this: GroupChatHdlrs => + + def handle(msg: SendGroupChatMessageFromApiSysPubMsg, state: MeetingState2x, + liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = { + + log.debug("RECEIVED SendGroupChatMessageFromApiSysPubMsg {}", msg) + + val chatDisabled: Boolean = liveMeeting.props.meetingProp.disabledFeatures.contains("chat") + if (!chatDisabled) { + val newState = for { + sender <- GroupChatApp.findGroupChatUser(SystemUser.ID, liveMeeting.users2x) + chat <- state.groupChats.find(GroupChatApp.MAIN_PUBLIC_CHAT) + } yield { + val groupChatMsgFromUser = GroupChatMsgFromUser(sender.id, sender.copy(name = msg.body.userName), msg.body.message) + val gcm = GroupChatApp.toGroupChatMessage(sender.copy(name = msg.body.userName), groupChatMsgFromUser, emphasizedText = true) + val gcs = GroupChatApp.addGroupChatMessage(liveMeeting.props.meetingProp.intId, chat, state.groupChats, gcm, GroupChatMessageType.API) + + val event = buildGroupChatMessageBroadcastEvtMsg( + liveMeeting.props.meetingProp.intId, + msg.body.userName, GroupChatApp.MAIN_PUBLIC_CHAT, gcm + ) + + bus.outGW.send(event) + + state.update(gcs) + } + + newState match { + case Some(ns) => ns + case None => state + } + } else { + state + } + } + +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala index e7e6b79efe..884716d7d2 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SendGroupChatMessageMsgHdlr.scala @@ -16,6 +16,14 @@ trait SendGroupChatMessageMsgHdlr extends HandlerHelpers { def handle(msg: SendGroupChatMessageMsg, state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = { + def determineMessageType(metadata: Map[String, Any]): String = { + if (metadata.contains("pluginName")) { + GroupChatMessageType.PLUGIN + } else { + GroupChatMessageType.DEFAULT + } + } + val chatDisabled: Boolean = liveMeeting.props.meetingProp.disabledFeatures.contains("chat") var chatLocked: Boolean = false @@ -59,8 +67,10 @@ trait SendGroupChatMessageMsgHdlr extends HandlerHelpers { !chatIsPrivate && sender.role == Roles.MODERATOR_ROLE - val gcm = GroupChatApp.toGroupChatMessage(sender, msg.body.msg, emphasizedText) - val gcs = GroupChatApp.addGroupChatMessage(liveMeeting.props.meetingProp.intId, chat, state.groupChats, gcm) + val messageType = determineMessageType(msg.body.msg.metadata) + + val gcm = GroupChatApp.toGroupChatMessage(sender, msg.body.msg, emphasizedText, msg.body.msg.metadata) + val gcs = GroupChatApp.addGroupChatMessage(liveMeeting.props.meetingProp.intId, chat, state.groupChats, gcm, messageType) val event = buildGroupChatMessageBroadcastEvtMsg( liveMeeting.props.meetingProp.intId, diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SetGroupChatLastSeenReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SetGroupChatLastSeenReqMsgHdlr.scala new file mode 100644 index 0000000000..50ab80641f --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SetGroupChatLastSeenReqMsgHdlr.scala @@ -0,0 +1,21 @@ +package org.bigbluebutton.core.apps.groupchats + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.db.ChatUserDAO +import org.bigbluebutton.core.models.Users2x +import org.bigbluebutton.core.running.LiveMeeting +import java.sql.Timestamp +import java.time.Instant + +trait SetGroupChatLastSeenReqMsgHdlr { + def handle(msg: SetGroupChatLastSeenReqMsg, liveMeeting: LiveMeeting): Unit = { + for { + user <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId) + } yield { + val lastSeenAtInstant = Instant.parse(msg.body.lastSeenAt) + val lastSeenAtTimestamp = Timestamp.from(lastSeenAtInstant) + + ChatUserDAO.updateChatLastSeen(liveMeeting.props.meetingProp.intId, msg.body.chatId, user.intId, lastSeenAtTimestamp) + } + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SetGroupChatVisibleReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SetGroupChatVisibleReqMsgHdlr.scala new file mode 100644 index 0000000000..ef2aa65237 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SetGroupChatVisibleReqMsgHdlr.scala @@ -0,0 +1,17 @@ +package org.bigbluebutton.core.apps.groupchats + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.bus.MessageBus +import org.bigbluebutton.core.db.ChatUserDAO +import org.bigbluebutton.core.models.Users2x +import org.bigbluebutton.core.running.{ LiveMeeting, LogHelper } + +trait SetGroupChatVisibleReqMsgHdlr { + def handle(msg: SetGroupChatVisibleReqMsg, liveMeeting: LiveMeeting): Unit = { + for { + user <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId) + } yield { + ChatUserDAO.updateChatVisible(liveMeeting.props.meetingProp.intId, msg.body.chatId, user.intId, msg.body.visible) + } + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SyncGetGroupChatsInfoMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SyncGetGroupChatsInfoMsgHdlr.scala deleted file mode 100644 index efb5cb1d8e..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/groupchats/SyncGetGroupChatsInfoMsgHdlr.scala +++ /dev/null @@ -1,53 +0,0 @@ -package org.bigbluebutton.core.apps.groupchats - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.bus.MessageBus -import org.bigbluebutton.core.domain.MeetingState2x -import org.bigbluebutton.core.running.LiveMeeting - -trait SyncGetGroupChatsInfoMsgHdlr { - this: GroupChatHdlrs => - - def handleSyncGetGroupChatsInfo(state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = { - - def buildSyncGetGroupChatsRespMsg(allChats: Vector[GroupChatInfo]): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp") - val envelope = BbbCoreEnvelope(SyncGetGroupChatsRespMsg.NAME, routing) - val header = BbbClientMsgHeader(SyncGetGroupChatsRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp") - val body = SyncGetGroupChatsRespMsgBody(allChats) - val event = SyncGetGroupChatsRespMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - - def buildSyncGetGroupChatMsgsRespMsg(msgs: Vector[GroupChatMsgToUser], chatId: String): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp") - val envelope = BbbCoreEnvelope(SyncGetGroupChatMsgsRespMsg.NAME, routing) - val header = BbbClientMsgHeader(SyncGetGroupChatMsgsRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp") - val body = SyncGetGroupChatMsgsRespMsgBody(chatId, msgs) - val event = SyncGetGroupChatMsgsRespMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - - // fetching all the group chats in the meeting - val chats = GroupChatApp.getAllGroupChatsInMeeting(state) - - // mapping group chats, while fetching and publishing messages for each group chat - val allChats = chats map (pc => { - - val msgs = pc.msgs.toVector map (m => GroupChatMsgToUser(m.id, m.createdOn, m.correlationId, - m.sender, m.chatEmphasizedText, m.message)) - val respMsg = buildSyncGetGroupChatMsgsRespMsg(msgs, pc.id) - bus.outGW.send(respMsg) - - GroupChatInfo(pc.id, pc.access, pc.createdBy, pc.users) - }) - - // publishing a message with the group chat info - val respMsg = buildSyncGetGroupChatsRespMsg(allChats) - bus.outGW.send(respMsg) - - state - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/meeting/SyncGetMeetingInfoRespMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/meeting/SyncGetMeetingInfoRespMsgHdlr.scala deleted file mode 100755 index 6d51ac8887..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/meeting/SyncGetMeetingInfoRespMsgHdlr.scala +++ /dev/null @@ -1,21 +0,0 @@ -package org.bigbluebutton.core.apps.meeting - -import org.bigbluebutton.common2.domain.DefaultProps -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.running.OutMsgRouter - -trait SyncGetMeetingInfoRespMsgHdlr { - - val outGW: OutMsgRouter - - def handleSyncGetMeetingInfoRespMsg(props: DefaultProps): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, props.meetingProp.intId, "nodeJSapp") - val envelope = BbbCoreEnvelope(SyncGetMeetingInfoRespMsg.NAME, routing) - val header = BbbCoreBaseHeader(SyncGetMeetingInfoRespMsg.NAME) - - val body = SyncGetMeetingInfoRespMsgBody(props) - val event = SyncGetMeetingInfoRespMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - outGW.send(msgEvent) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/meeting/ValidateConnAuthTokenSysMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/meeting/ValidateConnAuthTokenSysMsgHdlr.scala deleted file mode 100755 index e440fa2a6c..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/meeting/ValidateConnAuthTokenSysMsgHdlr.scala +++ /dev/null @@ -1,30 +0,0 @@ -package org.bigbluebutton.core.apps.meeting - -import org.bigbluebutton.common2.msgs.ValidateConnAuthTokenSysMsg -import org.bigbluebutton.core.models.RegisteredUsers -import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } -import org.bigbluebutton.core2.message.senders.MsgBuilder - -trait ValidateConnAuthTokenSysMsgHdlr { - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleValidateConnAuthTokenSysMsg(msg: ValidateConnAuthTokenSysMsg): Unit = { - val regUser = RegisteredUsers.getRegisteredUserWithToken( - msg.body.authToken, - msg.body.userId, - liveMeeting.registeredUsers - ) - - regUser match { - case Some(u) => - val event = MsgBuilder.buildValidateConnAuthTokenSysRespMsg(msg.body.meetingId, msg.body.userId, - true, msg.body.connId, msg.body.app) - outGW.send(event) - case None => - val event = MsgBuilder.buildValidateConnAuthTokenSysRespMsg(msg.body.meetingId, msg.body.userId, - false, msg.body.connId, msg.body.app) - outGW.send(event) - } - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/pads/PadCreateGroupReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/pads/PadCreateGroupReqMsgHdlr.scala deleted file mode 100644 index 1edbce2d9e..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/pads/PadCreateGroupReqMsgHdlr.scala +++ /dev/null @@ -1,24 +0,0 @@ -package org.bigbluebutton.core.apps.pads - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.bus.MessageBus -import org.bigbluebutton.core.models.Pads -import org.bigbluebutton.core.running.LiveMeeting - -trait PadCreateGroupReqMsgHdlr { - this: PadsApp2x => - - def handle(msg: PadCreateGroupReqMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { - - val padEnabled = msg.body.model match { - case "notes" => !liveMeeting.props.meetingProp.disabledFeatures.contains("sharedNotes") - case "captions" => !liveMeeting.props.meetingProp.disabledFeatures.contains("captions") - case _ => false - } - - if (padEnabled && !Pads.hasGroup(liveMeeting.pads, msg.body.externalId)) { - Pads.addGroup(liveMeeting.pads, msg.body.externalId, msg.body.model, msg.body.name, msg.header.userId) - PadslHdlrHelpers.broadcastPadCreateGroupCmdMsg(bus.outGW, liveMeeting.props.meetingProp.intId, msg.body.externalId, msg.body.model) - } - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/pads/PadsApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/pads/PadsApp2x.scala index 29402d16bd..68804e185c 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/pads/PadsApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/pads/PadsApp2x.scala @@ -3,8 +3,7 @@ package org.bigbluebutton.core.apps.pads import org.apache.pekko.actor.ActorContext class PadsApp2x(implicit val context: ActorContext) - extends PadCreateGroupReqMsgHdlr - with PadGroupCreatedEvtMsgHdlr + extends PadGroupCreatedEvtMsgHdlr with PadCreateReqMsgHdlr with PadCreatedEvtMsgHdlr with PadCreateSessionReqMsgHdlr diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelDeleteEntryMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelDeleteEntryMsgHdlr.scala index 17c8ca7e78..2cc9f5104c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelDeleteEntryMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelDeleteEntryMsgHdlr.scala @@ -25,21 +25,21 @@ trait PluginDataChannelDeleteEntryMsgHdlr extends HandlerHelpers { println(s"Data channel '${msg.body.channelName}' not found in plugin '${msg.body.pluginName}'.") } else { val hasPermission = for { - deletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).deletePermission + replaceOrDeletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).replaceOrDeletePermission } yield { - deletePermission.toLowerCase match { + replaceOrDeletePermission.toLowerCase match { case "all" => true case "moderator" => user.role == Roles.MODERATOR_ROLE case "presenter" => user.presenter - case "sender" => { - val senderUserId = PluginDataChannelEntryDAO.getMessageSender( + case "creator" => { + val creatorUserId = PluginDataChannelEntryDAO.getEntryCreator( meetingId, msg.body.pluginName, msg.body.channelName, msg.body.subChannelName, msg.body.entryId ) - senderUserId == msg.header.userId + creatorUserId == msg.header.userId } case _ => false } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelPushEntryMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelPushEntryMsgHdlr.scala index 32b0b52604..fc6b8c4c45 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelPushEntryMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelPushEntryMsgHdlr.scala @@ -25,9 +25,9 @@ trait PluginDataChannelPushEntryMsgHdlr extends HandlerHelpers { println(s"Data channel '${msg.body.channelName}' not found in plugin '${msg.body.pluginName}'.") } else { val hasPermission = for { - writePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).writePermission + pushPermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).pushPermission } yield { - writePermission.toLowerCase match { + pushPermission.toLowerCase match { case "all" => true case "moderator" => user.role == Roles.MODERATOR_ROLE case "presenter" => user.presenter diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelReplaceEntryMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelReplaceEntryMsgHdlr.scala new file mode 100755 index 0000000000..453f64587d --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelReplaceEntryMsgHdlr.scala @@ -0,0 +1,63 @@ +package org.bigbluebutton.core.apps.plugin + +import org.bigbluebutton.ClientSettings +import org.bigbluebutton.common2.msgs.PluginDataChannelReplaceEntryMsg +import org.bigbluebutton.core.db.{JsonUtils, PluginDataChannelEntryDAO} +import org.bigbluebutton.core.domain.MeetingState2x +import org.bigbluebutton.core.models.{Roles, Users2x} +import org.bigbluebutton.core.running.{HandlerHelpers, LiveMeeting} + +trait PluginDataChannelReplaceEntryMsgHdlr extends HandlerHelpers { + + def handle(msg: PluginDataChannelReplaceEntryMsg, state: MeetingState2x, liveMeeting: LiveMeeting): Unit = { + val pluginsDisabled: Boolean = liveMeeting.props.meetingProp.disabledFeatures.contains("plugins") + val meetingId = liveMeeting.props.meetingProp.intId + + for { + _ <- if (!pluginsDisabled) Some(()) else None + user <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId) + } yield { + val pluginsConfig = ClientSettings.getPluginsFromConfig(ClientSettings.clientSettingsFromFile) + + if (!pluginsConfig.contains(msg.body.pluginName)) { + println(s"Plugin '${msg.body.pluginName}' not found.") + } else if (!pluginsConfig(msg.body.pluginName).dataChannels.contains(msg.body.channelName)) { + println(s"Data channel '${msg.body.channelName}' not found in plugin '${msg.body.pluginName}'.") + } else { + val hasPermission = for { + replaceOrDeletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).replaceOrDeletePermission + } yield { + replaceOrDeletePermission.toLowerCase match { + case "all" => true + case "moderator" => user.role == Roles.MODERATOR_ROLE + case "presenter" => user.presenter + case "creator" => { + val creatorUserId = PluginDataChannelEntryDAO.getEntryCreator( + meetingId, + msg.body.pluginName, + msg.body.channelName, + msg.body.subChannelName, + msg.body.entryId + ) + creatorUserId == msg.header.userId + } + case _ => false + } + } + + if (!hasPermission.contains(true)) { + println(s"No permission to write in plugin: '${msg.body.pluginName}', data channel: '${msg.body.channelName}'.") + } else { + PluginDataChannelEntryDAO.replace( + msg.header.meetingId, + msg.body.pluginName, + msg.body.channelName, + msg.body.subChannelName, + msg.body.entryId, + JsonUtils.mapToJson(msg.body.payloadJson), + ) + } + } + } + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelResetMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelResetMsgHdlr.scala index 16ac38b0ae..32a403f862 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelResetMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginDataChannelResetMsgHdlr.scala @@ -25,9 +25,9 @@ trait PluginDataChannelResetMsgHdlr extends HandlerHelpers { println(s"Data channel '${msg.body.channelName}' not found in plugin '${msg.body.pluginName}'.") } else { val hasPermission = for { - deletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).deletePermission + replaceOrDeletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).replaceOrDeletePermission } yield { - deletePermission.toLowerCase match { + replaceOrDeletePermission.toLowerCase match { case "all" => true case "moderator" => user.role == Roles.MODERATOR_ROLE case "presenter" => user.presenter diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginHdlrs.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginHdlrs.scala index d9f8bb78f8..d1dbf285fc 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginHdlrs.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/plugin/PluginHdlrs.scala @@ -6,6 +6,7 @@ import org.bigbluebutton.common2.msgs.PluginDataChannelDeleteEntryMsgBody class PluginHdlrs(implicit val context: ActorContext) extends PluginDataChannelPushEntryMsgHdlr + with PluginDataChannelReplaceEntryMsgHdlr with PluginDataChannelDeleteEntryMsgHdlr with PluginDataChannelResetMsgHdlr { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/MakePresentationDownloadReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/MakePresentationDownloadReqMsgHdlr.scala index d2635d61f5..5f10fab2a1 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/MakePresentationDownloadReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/MakePresentationDownloadReqMsgHdlr.scala @@ -145,7 +145,7 @@ trait MakePresentationDownloadReqMsgHdlr extends RightsManagementTrait { && m.body.fileStateType == "Converted") { val reason = "Converted presentation download disabled for this meeting. (PDF format)" PermissionCheck.ejectUserForFailedPermission(meetingId, userId, reason, bus.outGW, liveMeeting) - } else if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, userId)) { + } else if (permissionFailed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, userId)) { val reason = "No permission to download presentation." PermissionCheck.ejectUserForFailedPermission(meetingId, userId, reason, bus.outGW, liveMeeting) } else if (currentPres.isEmpty) { @@ -210,11 +210,17 @@ trait MakePresentationDownloadReqMsgHdlr extends RightsManagementTrait { // Informs bbb-web about the token so that when we use it to upload the presentation, it is able to look it up in the list of tokens bus.outGW.send(buildPresentationUploadTokenSysPubMsg(parentMeetingId, userId, presentationUploadToken, filename, presentationId)) + var pres = new PresentationInPod(presentationId, default = false, current = false, name = filename, + pages = Map.empty, downloadable = false, downloadFileExtension = "", removable = true, filenameConverted = filename, + uploadCompleted = false, numPages = 0, errorMsgKey = "", errorDetails = Map.empty) + if (liveMeeting.props.meetingProp.disabledFeatures.contains("importPresentationWithAnnotationsFromBreakoutRooms")) { log.error(s"Capturing breakout rooms slides disabled in meeting ${meetingId}.") } else if (currentPres.isEmpty) { log.error(s"No presentation set in meeting ${meetingId}") + pres = pres.copy(errorMsgKey = "204") bus.outGW.send(buildBroadcastPresentationConversionUpdateEvtMsg(parentMeetingId, "204", jobId, filename, presentationUploadToken)) + PresPresentationDAO.updateConversionStarted(parentMeetingId, pres) } else { val allPages: Boolean = m.allPages val pageCount = currentPres.get.pages.size @@ -239,9 +245,13 @@ trait MakePresentationDownloadReqMsgHdlr extends RightsManagementTrait { val annotations = new StoredAnnotations(jobId, presId, storeAnnotationPages) bus.outGW.send(buildStoreAnnotationsInRedisSysMsg(annotations, liveMeeting)) } else { + pres = pres.copy(errorMsgKey = "204") + // Notify that no content is available to capture bus.outGW.send(buildBroadcastPresentationConversionUpdateEvtMsg(parentMeetingId, "204", jobId, filename, presentationUploadToken)) } + + PresPresentationDAO.updateConversionStarted(parentMeetingId, pres) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationConversionUpdatePubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationConversionUpdatePubMsgHdlr.scala index d1723b3cfb..ade50a4a32 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationConversionUpdatePubMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationConversionUpdatePubMsgHdlr.scala @@ -13,7 +13,12 @@ trait PresentationConversionUpdatePubMsgHdlr { def handle(msg: PresentationConversionUpdateSysPubMsg, state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = { - // broadcastEvent(msg) + val presentationId = msg.body.presentationId + val pres = new PresentationInPod(presentationId, msg.body.presName, default = false, current = false, Map.empty, downloadable = false, + "", removable = true, filenameConverted = msg.body.presName, uploadCompleted = false, numPages = 0, errorDetails = Map.empty) + + PresPresentationDAO.updateConversionStarted(liveMeeting.props.meetingProp.intId, pres) + state } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPodHdlrs.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPodHdlrs.scala index 527db49380..b40d98c9e9 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPodHdlrs.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/PresentationPodHdlrs.scala @@ -11,6 +11,7 @@ class PresentationPodHdlrs(implicit val context: ActorContext) with PresentationConversionCompletedSysPubMsgHdlr with PdfConversionInvalidErrorSysPubMsgHdlr with SetCurrentPagePubMsgHdlr + with SetPageInfiniteWhiteboardPubMsgHdlr with SetPresenterInDefaultPodInternalMsgHdlr with RemovePresentationPubMsgHdlr with SetPresentationDownloadablePubMsgHdlr @@ -22,7 +23,6 @@ class PresentationPodHdlrs(implicit val context: ActorContext) with MakePresentationDownloadReqMsgHdlr with ResizeAndMovePagePubMsgHdlr with SlideResizedPubMsgHdlr - with SyncGetPresentationPodsMsgHdlr with RemovePresentationPodPubMsgHdlr with PresentationPageConvertedSysMsgHdlr with PresentationPageConversionStartedSysMsgHdlr diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPageInfiniteWhiteboardPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPageInfiniteWhiteboardPubMsgHdlr.scala new file mode 100644 index 0000000000..6c0e9672da --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPageInfiniteWhiteboardPubMsgHdlr.scala @@ -0,0 +1,38 @@ +package org.bigbluebutton.core.apps.presentationpod + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } +import org.bigbluebutton.core.bus.MessageBus +import org.bigbluebutton.core.domain.MeetingState2x +import org.bigbluebutton.core.running.LiveMeeting +import org.bigbluebutton.core.db.PresPageDAO + +trait SetPageInfiniteWhiteboardPubMsgHdlr extends RightsManagementTrait { + this: PresentationPodHdlrs => + + def handle( + msg: SetPageInfiniteWhiteboardPubMsg, state: MeetingState2x, + liveMeeting: LiveMeeting, bus: MessageBus + ): MeetingState2x = { + + if (liveMeeting.props.meetingProp.disabledFeatures.contains("infiniteWhiteboard")) { + val meetingId = liveMeeting.props.meetingProp.intId + val reason = "Infinite whiteboard is disabled for this meeting." + PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting) + state + } else if (permissionFailed(PermissionCheck.GUEST_LEVEL, PermissionCheck.PRESENTER_LEVEL, liveMeeting.users2x, msg.header.userId)) { + val meetingId = liveMeeting.props.meetingProp.intId + val reason = "No permission to set infinite whiteboard." + PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting) + state + } else { + val pageId = msg.body.pageId + val infiniteWhiteboard = msg.body.infiniteWhiteboard + + PresPageDAO.updateInfiniteWhiteboard(pageId, infiniteWhiteboard) + + state + } + } +} + diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SyncGetPresentationPodsMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SyncGetPresentationPodsMsgHdlr.scala deleted file mode 100644 index 52d5358070..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SyncGetPresentationPodsMsgHdlr.scala +++ /dev/null @@ -1,35 +0,0 @@ -package org.bigbluebutton.core.apps.presentationpod - -import org.bigbluebutton.common2.domain.PresentationPodVO -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.bus.MessageBus -import org.bigbluebutton.core.domain.MeetingState2x -import org.bigbluebutton.core.running.LiveMeeting - -trait SyncGetPresentationPodsMsgHdlr { - this: PresentationPodHdlrs => - - def handleSyncGetPresentationPods(state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = { - - def buildSyncGetPresentationPodsRespMsg(pods: Vector[PresentationPodVO]): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp") - val envelope = BbbCoreEnvelope(SyncGetPresentationPodsRespMsg.NAME, routing) - val header = BbbClientMsgHeader(SyncGetPresentationPodsRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp") - - val body = SyncGetPresentationPodsRespMsgBody(pods) - val event = SyncGetPresentationPodsRespMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - - val pods = PresentationPodsApp.getAllPresentationPodsInMeeting(state) - - val podsVO = pods.map(pod => PresentationPodsApp.translatePresentationPodToVO(pod)) - val event = buildSyncGetPresentationPodsRespMsg(podsVO) - - bus.outGW.send(event) - - state - } - -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/screenshare/ScreenshareApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/screenshare/ScreenshareApp2x.scala index 9a74f80501..443f1ad6af 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/screenshare/ScreenshareApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/screenshare/ScreenshareApp2x.scala @@ -41,8 +41,7 @@ object ScreenshareApp2x { class ScreenshareApp2x(implicit val context: ActorContext) extends GetScreenshareStatusReqMsgHdlr with ScreenshareRtmpBroadcastStartedVoiceConfEvtMsgHdlr - with ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsgHdlr - with SyncGetScreenshareInfoRespMsgHdlr { + with ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsgHdlr { val log = Logging(context.system, getClass) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/screenshare/SyncGetScreenshareInfoRespMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/screenshare/SyncGetScreenshareInfoRespMsgHdlr.scala deleted file mode 100644 index 253433036f..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/screenshare/SyncGetScreenshareInfoRespMsgHdlr.scala +++ /dev/null @@ -1,39 +0,0 @@ -package org.bigbluebutton.core.apps.screenshare - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.apps.ScreenshareModel -import org.bigbluebutton.core.bus.MessageBus -import org.bigbluebutton.core.running.LiveMeeting - -trait SyncGetScreenshareInfoRespMsgHdlr { - this: ScreenshareApp2x => - - def handleSyncGetScreenshareInfoRespMsg(liveMeeting: LiveMeeting, bus: MessageBus): Unit = { - val routing = Routing.addMsgToClientRouting( - MessageTypes.BROADCAST_TO_MEETING, - liveMeeting.props.meetingProp.intId, - "nodeJSapp" - ) - val envelope = BbbCoreEnvelope(SyncGetScreenshareInfoRespMsg.NAME, routing) - val header = BbbClientMsgHeader( - SyncGetScreenshareInfoRespMsg.NAME, - liveMeeting.props.meetingProp.intId, - "nodeJSapp" - ) - val body = SyncGetScreenshareInfoRespMsgBody( - ScreenshareModel.isBroadcastingRTMP(liveMeeting.screenshareModel), - ScreenshareModel.getVoiceConf(liveMeeting.screenshareModel), - ScreenshareModel.getScreenshareConf(liveMeeting.screenshareModel), - ScreenshareModel.getRTMPBroadcastingUrl(liveMeeting.screenshareModel), - ScreenshareModel.getScreenshareVideoWidth(liveMeeting.screenshareModel), - ScreenshareModel.getScreenshareVideoHeight(liveMeeting.screenshareModel), - ScreenshareModel.getTimestamp(liveMeeting.screenshareModel), - ScreenshareModel.getHasAudio(liveMeeting.screenshareModel), - ScreenshareModel.getContentType(liveMeeting.screenshareModel) - ) - val event = SyncGetScreenshareInfoRespMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - - bus.outGW.send(msgEvent) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/CreateTimerReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/CreateTimerReqMsgHdlr.scala deleted file mode 100644 index bb009f5172..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/CreateTimerReqMsgHdlr.scala +++ /dev/null @@ -1,17 +0,0 @@ -package org.bigbluebutton.core.apps.timer - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.bus.MessageBus -import org.bigbluebutton.core.running.LiveMeeting -import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait, TimerModel } -import org.bigbluebutton.core.db.TimerDAO - -trait CreateTimerPubMsgHdlr extends RightsManagementTrait { - this: TimerApp2x => - - def handle(msg: CreateTimerPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { - log.debug("Received CreateTimerPubMsg {}", CreateTimerPubMsg) - TimerModel.createTimer(liveMeeting.timerModel, msg.body.stopwatch, msg.body.time, msg.body.accumulated, msg.body.track) - TimerDAO.update(liveMeeting.props.meetingProp.intId, liveMeeting.timerModel) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/StartTimerReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/StartTimerReqMsgHdlr.scala index d2d1a7b298..439f47a561 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/StartTimerReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/StartTimerReqMsgHdlr.scala @@ -1,6 +1,7 @@ package org.bigbluebutton.core.apps.timer import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.apps.TimerModel.{ isRunning, isStopwatch } import org.bigbluebutton.core.bus.MessageBus import org.bigbluebutton.core.running.LiveMeeting import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait, TimerModel } @@ -30,7 +31,6 @@ trait StartTimerReqMsgHdlr extends RightsManagementTrait { val reason = "You need to be the presenter or moderator to start timer" PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting) } else { - TimerModel.setStartedAt(liveMeeting.timerModel, System.currentTimeMillis()) TimerModel.setRunning(liveMeeting.timerModel, running = true) TimerDAO.update(liveMeeting.props.meetingProp.intId, liveMeeting.timerModel) broadcastEvent() diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/SwitchTimerReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/SwitchTimerReqMsgHdlr.scala index 526eb4a4c9..964a63606c 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/SwitchTimerReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/SwitchTimerReqMsgHdlr.scala @@ -32,7 +32,7 @@ trait SwitchTimerReqMsgHdlr extends RightsManagementTrait { val reason = "You need to be the presenter or moderator to switch timer" PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, bus.outGW, liveMeeting) } else { - if (TimerModel.getStopwatch(liveMeeting.timerModel) != msg.body.stopwatch) { + if (TimerModel.isStopwatch(liveMeeting.timerModel) != msg.body.stopwatch) { TimerModel.setStopwatch(liveMeeting.timerModel, msg.body.stopwatch) TimerModel.setRunning(liveMeeting.timerModel, running = false) TimerModel.reset(liveMeeting.timerModel) //Reset on switch Stopwatch/Timer diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/TimerApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/TimerApp2x.scala index 09909c7eb7..8bbcf11e11 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/TimerApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/TimerApp2x.scala @@ -4,16 +4,14 @@ import org.apache.pekko.actor.ActorContext import org.apache.pekko.event.Logging class TimerApp2x(implicit val context: ActorContext) - extends CreateTimerPubMsgHdlr - with ActivateTimerReqMsgHdlr + extends ActivateTimerReqMsgHdlr with DeactivateTimerReqMsgHdlr with StartTimerReqMsgHdlr with StopTimerReqMsgHdlr with SwitchTimerReqMsgHdlr with SetTimerReqMsgHdlr with ResetTimerReqMsgHdlr - with SetTrackReqMsgHdlr - with TimerEndedPubMsgHdlr { + with SetTrackReqMsgHdlr { val log = Logging(context.system, getClass) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/TimerEndedPubMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/TimerEndedPubMsgHdlr.scala deleted file mode 100644 index 1c85ba59be..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/timer/TimerEndedPubMsgHdlr.scala +++ /dev/null @@ -1,31 +0,0 @@ -package org.bigbluebutton.core.apps.timer - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.bus.MessageBus -import org.bigbluebutton.core.running.LiveMeeting -import org.bigbluebutton.core.apps.{ RightsManagementTrait, TimerModel } -import org.bigbluebutton.core.db.TimerDAO - -trait TimerEndedPubMsgHdlr extends RightsManagementTrait { - this: TimerApp2x => - - def handle(msg: TimerEndedPubMsg, liveMeeting: LiveMeeting, bus: MessageBus): Unit = { - log.debug("Received timerEndedPubMsg {}", TimerEndedPubMsg) - def broadcastEvent(): Unit = { - val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") - val envelope = BbbCoreEnvelope(TimerEndedEvtMsg.NAME, routing) - val header = BbbCoreHeaderWithMeetingId( - TimerEndedEvtMsg.NAME, - liveMeeting.props.meetingProp.intId - ) - val body = TimerEndedEvtMsgBody() - val event = TimerEndedEvtMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - bus.outGW.send(msgEvent) - } - - TimerModel.setEndedAt(liveMeeting.timerModel, System.currentTimeMillis()) - TimerDAO.update(liveMeeting.props.meetingProp.intId, liveMeeting.timerModel) - broadcastEvent() - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserAwayReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserAwayReqMsgHdlr.scala index fdcdf6247c..bec59c27e9 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserAwayReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserAwayReqMsgHdlr.scala @@ -39,21 +39,12 @@ trait ChangeUserAwayReqMsgHdlr extends RightsManagementTrait { user <- Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId) newUserState <- Users2x.setUserAway(liveMeeting.users2x, user.intId, msg.body.away) } yield { - if (msg.body.away && user.emoji == "") { - Users2x.setEmojiStatus(liveMeeting.users2x, msg.body.userId, "away") - outGW.send(MsgBuilder.buildUserEmojiChangedEvtMsg(liveMeeting.props.meetingProp.intId, msg.body.userId, "away")) - } - - if (msg.body.away == false && user.emoji == "away") { - Users2x.setEmojiStatus(liveMeeting.users2x, msg.body.userId, "none") - outGW.send(MsgBuilder.buildUserEmojiChangedEvtMsg(liveMeeting.props.meetingProp.intId, msg.body.userId, "none")) - } - val msgMeta = Map( "away" -> msg.body.away ) - if (!(user.role == Roles.VIEWER_ROLE && user.locked && permissions.disablePubChat) && ((user.away && !msg.body.away) || (!user.away && msg.body.away))) { + if (!(user.role == Roles.VIEWER_ROLE && user.locked && permissions.disablePubChat) + && ((user.away && !msg.body.away) || (!user.away && msg.body.away))) { ChatMessageDAO.insertSystemMsg(liveMeeting.props.meetingProp.intId, GroupChatApp.MAIN_PUBLIC_CHAT, "", GroupChatMessageType.USER_AWAY_STATUS_MSG, msgMeta, user.name) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserEmojiCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserEmojiCmdMsgHdlr.scala deleted file mode 100755 index 20318d9a02..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserEmojiCmdMsgHdlr.scala +++ /dev/null @@ -1,61 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.models.Users2x -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } -import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } -import org.bigbluebutton.core2.message.senders.MsgBuilder - -trait ChangeUserEmojiCmdMsgHdlr extends RightsManagementTrait { - this: BaseMeetingActor => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleChangeUserEmojiCmdMsg(msg: ChangeUserEmojiCmdMsg) { - val isUserSettingOwnEmoji = (msg.header.userId == msg.body.userId) - - val isUserModerator = !permissionFailed( - PermissionCheck.MOD_LEVEL, - PermissionCheck.VIEWER_LEVEL, - liveMeeting.users2x, - msg.header.userId - ) - - val isUserPresenter = !permissionFailed( - PermissionCheck.VIEWER_LEVEL, - PermissionCheck.PRESENTER_LEVEL, - liveMeeting.users2x, - msg.header.userId - ) - - val initialEmojiState = Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId).get.emoji - val nextEmojiState = msg.body.emoji - - if (isUserSettingOwnEmoji - || isUserModerator && nextEmojiState.equals("none") - || isUserPresenter && initialEmojiState.equals("raiseHand") && nextEmojiState.equals("none")) { - for { - uvo <- Users2x.setEmojiStatus(liveMeeting.users2x, msg.body.userId, msg.body.emoji) - } yield { - outGW.send(MsgBuilder.buildUserEmojiChangedEvtMsg(liveMeeting.props.meetingProp.intId, msg.body.userId, msg.body.emoji)) - - if (initialEmojiState == "raiseHand" || nextEmojiState == "raiseHand") { - Users2x.setUserRaiseHand(liveMeeting.users2x, msg.body.userId, msg.body.emoji == "raiseHand") - outGW.send(MsgBuilder.buildUserRaiseHandChangedEvtMsg(liveMeeting.props.meetingProp.intId, msg.body.userId, msg.body.emoji == "raiseHand")) - } - - if (initialEmojiState == "away" || nextEmojiState == "away") { - Users2x.setUserAway(liveMeeting.users2x, msg.body.userId, msg.body.emoji == "away") - outGW.send(MsgBuilder.buildUserAwayChangedEvtMsg(liveMeeting.props.meetingProp.intId, msg.body.userId, msg.body.emoji == "away")) - } - - } - } else { - val meetingId = liveMeeting.props.meetingProp.intId - val reason = "No permission to clear change user emoji status." - PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting) - } - } - -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserMobileFlagReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserMobileFlagReqMsgHdlr.scala deleted file mode 100644 index 77c08962ab..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserMobileFlagReqMsgHdlr.scala +++ /dev/null @@ -1,42 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.apps.{ RightsManagementTrait } -import org.bigbluebutton.core.models.{ UserState, Users2x } -import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } - -trait ChangeUserMobileFlagReqMsgHdlr extends RightsManagementTrait { - this: UsersApp => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleChangeUserMobileFlagReqMsg(msg: ChangeUserMobileFlagReqMsg): Unit = { - log.info("handleChangeUserMobileFlagReqMsg: mobile={} userId={}", msg.body.mobile, msg.body.userId) - - def broadcastUserMobileChanged(user: UserState, mobile: Boolean): Unit = { - val routingChange = Routing.addMsgToClientRouting( - MessageTypes.BROADCAST_TO_MEETING, - liveMeeting.props.meetingProp.intId, user.intId - ) - val envelopeChange = BbbCoreEnvelope(UserMobileFlagChangedEvtMsg.NAME, routingChange) - val headerChange = BbbClientMsgHeader(UserMobileFlagChangedEvtMsg.NAME, liveMeeting.props.meetingProp.intId, - user.intId) - - val bodyChange = UserMobileFlagChangedEvtMsgBody(user.intId, mobile) - val eventChange = UserMobileFlagChangedEvtMsg(headerChange, bodyChange) - val msgEventChange = BbbCommonEnvCoreMsg(envelopeChange, eventChange) - outGW.send(msgEventChange) - } - - for { - user <- Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId) - } yield { - if (user.mobile != msg.body.mobile) { - val userMobile = Users2x.setMobile(liveMeeting.users2x, user) - broadcastUserMobileChanged(userMobile, msg.body.mobile) - } - } - - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserRaiseHandReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserRaiseHandReqMsgHdlr.scala index 1eab60093b..c8f37c9e04 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserRaiseHandReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ChangeUserRaiseHandReqMsgHdlr.scala @@ -51,17 +51,6 @@ trait ChangeUserRaiseHandReqMsgHdlr extends RightsManagementTrait { user <- Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId) newUserState <- Users2x.setUserRaiseHand(liveMeeting.users2x, user.intId, msg.body.raiseHand) } yield { - - if (msg.body.raiseHand && user.emoji == "") { - Users2x.setEmojiStatus(liveMeeting.users2x, msg.body.userId, "raiseHand") - outGW.send(MsgBuilder.buildUserEmojiChangedEvtMsg(liveMeeting.props.meetingProp.intId, msg.body.userId, "raiseHand")) - } - - if (msg.body.raiseHand == false && user.emoji == "raiseHand") { - Users2x.setEmojiStatus(liveMeeting.users2x, msg.body.userId, "none") - outGW.send(MsgBuilder.buildUserEmojiChangedEvtMsg(liveMeeting.props.meetingProp.intId, msg.body.userId, "none")) - } - broadcast(newUserState, msg.body.raiseHand) } } else { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ClearAllUsersEmojiCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ClearAllUsersEmojiCmdMsgHdlr.scala deleted file mode 100644 index b50d6d1c20..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ClearAllUsersEmojiCmdMsgHdlr.scala +++ /dev/null @@ -1,47 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.models.Users2x -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } -import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } - -trait ClearAllUsersEmojiCmdMsgHdlr extends RightsManagementTrait { - this: BaseMeetingActor => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleClearAllUsersEmojiCmdMsg(msg: ClearAllUsersEmojiCmdMsg) { - val isUserModerator = !permissionFailed( - PermissionCheck.MOD_LEVEL, - PermissionCheck.VIEWER_LEVEL, - liveMeeting.users2x, - msg.header.userId - ) - - if (isUserModerator) { - for { - user <- Users2x.findAll(liveMeeting.users2x) - } yield { - Users2x.setEmojiStatus(liveMeeting.users2x, user.intId, "none") - Users2x.setUserAway(liveMeeting.users2x, user.intId, false) - Users2x.setUserRaiseHand(liveMeeting.users2x, user.intId, false) - } - sendClearedAllUsersEmojiEvtMsg(outGW, liveMeeting.props.meetingProp.intId, msg.header.userId) - } else { - val meetingId = liveMeeting.props.meetingProp.intId - val reason = "No permission to clear users reactions." - PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting) - } - } - - def sendClearedAllUsersEmojiEvtMsg(outGW: OutMsgRouter, meetingId: String, userId: String): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId) - val envelope = BbbCoreEnvelope(ClearedAllUsersEmojiEvtMsg.NAME, routing) - val header = BbbClientMsgHeader(ClearedAllUsersEmojiEvtMsg.NAME, meetingId, userId) - val body = ClearedAllUsersEmojiEvtMsgBody() - val event = ClearedAllUsersEmojiEvtMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - outGW.send(msgEvent) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/EjectUserFromMeetingCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/EjectUserFromMeetingCmdMsgHdlr.scala index b348d3f9e7..d81af4a297 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/EjectUserFromMeetingCmdMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/EjectUserFromMeetingCmdMsgHdlr.scala @@ -70,9 +70,6 @@ trait EjectUserFromMeetingCmdMsgHdlr extends RightsManagementTrait { log.info("Eject user {} userId={} by {} and ban=" + banUser + " in meeting {}", registeredUser.name, userId, ejectedBy, meetingId) - // send a system message to force disconnection - Sender.sendDisconnectClientSysMsg(meetingId, ru.id, ejectedBy, EjectReasonCode.EJECT_USER, outGW) - // Force reconnection with graphql to refresh permissions Sender.sendForceUserGraphqlReconnectionSysMsg(liveMeeting.props.meetingProp.intId, registeredUser.id, registeredUser.sessionToken, EjectReasonCode.EJECT_USER, outGW) } @@ -89,8 +86,6 @@ trait EjectUserFromMeetingCmdMsgHdlr extends RightsManagementTrait { EjectReasonCode.EJECT_USER, ban = false ) - // send a system message to force disconnection - Sender.sendDisconnectClientSysMsg(meetingId, userId, ejectedBy, EjectReasonCode.EJECT_USER, outGW) // Force reconnection with graphql to refresh permissions Sender.sendForceUserGraphqlReconnectionSysMsg(liveMeeting.props.meetingProp.intId, registeredUser.id, registeredUser.sessionToken, EjectReasonCode.EJECT_USER, outGW) @@ -122,8 +117,6 @@ trait EjectUserFromMeetingSysMsgHdlr { EjectReasonCode.SYSTEM_EJECT_USER, ban = false ) - // send a system message to force disconnection - Sender.sendDisconnectClientSysMsg(meetingId, userId, ejectedBy, EjectReasonCode.SYSTEM_EJECT_USER, outGW) // Force reconnection with graphql to refresh permissions for { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetLockSettingsReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetLockSettingsReqMsgHdlr.scala deleted file mode 100755 index a20b6fb078..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetLockSettingsReqMsgHdlr.scala +++ /dev/null @@ -1,66 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter, LiveMeeting } -import org.bigbluebutton.core2.MeetingStatus2x -import org.bigbluebutton.core2.Permissions -import org.bigbluebutton.core.bus.MessageBus -import org.bigbluebutton.core.domain.MeetingState2x - -trait GetLockSettingsReqMsgHdlr { - this: MeetingActor => - - val outGW: OutMsgRouter - - def buildLockSettingsResp(meetingId: String, requestedBy: String, settings: Permissions): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, requestedBy) - val envelope = BbbCoreEnvelope(GetLockSettingsRespMsg.NAME, routing) - val body = GetLockSettingsRespMsgBody( - disableCam = settings.disableCam, - disableMic = settings.disableMic, - disablePrivChat = settings.disablePrivChat, - disablePubChat = settings.disablePubChat, - disableNotes = settings.disableNotes, - hideUserList = settings.hideUserList, - lockOnJoin = settings.lockOnJoin, - lockOnJoinConfigurable = settings.lockOnJoinConfigurable, - hideViewersCursor = settings.hideViewersCursor, - hideViewersAnnotation = settings.hideViewersAnnotation - ) - val header = BbbClientMsgHeader(GetLockSettingsRespMsg.NAME, meetingId, requestedBy) - val event = GetLockSettingsRespMsg(header, body) - BbbCommonEnvCoreMsg(envelope, event) - } - def buildNotInitializedResp(meetingId: String, requestedBy: String): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, requestedBy) - val envelope = BbbCoreEnvelope(LockSettingsNotInitializedRespMsg.NAME, routing) - val body = LockSettingsNotInitializedRespMsgBody(requestedBy) - val header = BbbClientMsgHeader(LockSettingsNotInitializedRespMsg.NAME, meetingId, requestedBy) - val event = LockSettingsNotInitializedRespMsg(header, body) - BbbCommonEnvCoreMsg(envelope, event) - } - - def handleGetLockSettingsReqMsg(msg: GetLockSettingsReqMsg): Unit = { - if (MeetingStatus2x.permisionsInitialized(liveMeeting.status)) { - val settings = MeetingStatus2x.getPermissions(liveMeeting.status) - val event = buildLockSettingsResp(props.meetingProp.intId, msg.body.requesterId, settings) - outGW.send(event) - } else { - val event = buildNotInitializedResp(props.meetingProp.intId, msg.body.requesterId) - outGW.send(event) - } - } - - def handleSyncGetLockSettingsMsg(state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = { - if (MeetingStatus2x.permisionsInitialized(liveMeeting.status)) { - val settings = MeetingStatus2x.getPermissions(liveMeeting.status) - val event = buildLockSettingsResp(props.meetingProp.intId, "nodeJSapp", settings) - bus.outGW.send(event) - } else { - val event = buildNotInitializedResp(props.meetingProp.intId, "nodeJSapp") - bus.outGW.send(event) - } - - state - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetUserApiMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetUserApiMsgHdlr.scala new file mode 100644 index 0000000000..38183d80f7 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetUserApiMsgHdlr.scala @@ -0,0 +1,64 @@ +package org.bigbluebutton.core.apps.users + +import org.apache.pekko.actor.ActorRef +import org.bigbluebutton.core.api.{ ApiResponseFailure, ApiResponseSuccess, GetUserApiMsg, UserInfosApiMsg } +import org.bigbluebutton.core.models.{ RegisteredUser, RegisteredUsers, Roles, Users2x } +import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core2.MeetingStatus2x + +trait GetUserApiMsgHdlr extends HandlerHelpers { + this: UsersApp => + + val liveMeeting: LiveMeeting + val outGW: OutMsgRouter + + def handleGetUserApiMsg(msg: GetUserApiMsg, actorRef: ActorRef): Unit = { + RegisteredUsers.findWithSessionToken(msg.sessionToken, liveMeeting.registeredUsers) match { + case Some(regUser) => + log.debug("replying GetUserApiMsg with success") + actorRef ! ApiResponseSuccess("User found!", UserInfosApiMsg(getUserInfoResponse(regUser))) + case None => + log.debug("User not found, sending failure message") + actorRef ! ApiResponseFailure("User not found", Map()) + } + } + + private def getUserInfoResponse(regUser: RegisteredUser): Map[String, Any] = { + val isModerator = (regUser.role == Roles.MODERATOR_ROLE) + val isLocked = Users2x.findWithIntId(liveMeeting.users2x, regUser.id).exists(u => u.locked) + val userStateExists = Users2x.findWithIntId(liveMeeting.users2x, regUser.id).nonEmpty + + val currentlyInMeeting = regUser.joined && !regUser.loggedOut && !regUser.ejected && userStateExists + + val permissions = MeetingStatus2x.getPermissions(liveMeeting.status) + + var userInfos: Map[String, Any] = Map() + userInfos += ("returncode" -> "SUCCESS") + userInfos += ("meetingID" -> liveMeeting.props.meetingProp.intId) + userInfos += ("externMeetingID" -> liveMeeting.props.meetingProp.extId) + userInfos += ("externUserID" -> regUser.externId) + userInfos += ("internalUserID" -> regUser.id) + userInfos += ("currentlyInMeeting" -> currentlyInMeeting) + userInfos += ("authToken" -> regUser.authToken) + userInfos += ("sessionToken" -> regUser.sessionToken) + userInfos += ("role" -> regUser.role) + userInfos += ("guest" -> regUser.guest) + userInfos += ("guestStatus" -> regUser.guestStatus) + userInfos += ("moderator" -> isModerator) + userInfos += ("presenter" -> Users2x.userIsInPresenterGroup(liveMeeting.users2x, regUser.id)) + if (isModerator || !isLocked) { + userInfos += ("hideViewersCursor" -> false) + userInfos += ("hideViewersAnnotation" -> false) + userInfos += ("hideUserList" -> false) + userInfos += ("webcamsOnlyForModerator" -> false) + } else { + userInfos += ("hideViewersCursor" -> permissions.hideViewersCursor) + userInfos += ("hideViewersAnnotation" -> permissions.hideViewersAnnotation) + userInfos += ("hideUserList" -> permissions.hideUserList) + userInfos += ("webcamsOnlyForModerator" -> MeetingStatus2x.webcamsOnlyForModeratorEnabled(liveMeeting.status)) + } + + userInfos + } + +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetUsersMeetingReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetUsersMeetingReqMsgHdlr.scala deleted file mode 100755 index 350c6c68cf..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetUsersMeetingReqMsgHdlr.scala +++ /dev/null @@ -1,16 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs.GetUsersMeetingReqMsg -import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting, OutMsgRouter } - -trait GetUsersMeetingReqMsgHdlr extends HandlerHelpers { - this: UsersApp => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleGetUsersMeetingReqMsg(msg: GetUsersMeetingReqMsg): Unit = { - sendAllUsersInMeeting(msg.body.userId) - sendAllVoiceUsersInMeeting(msg.body.userId, liveMeeting.voiceUsers, liveMeeting.props.meetingProp.intId) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/MuteUserCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/MuteUserCmdMsgHdlr.scala index d29f40d113..e383ce3ba5 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/MuteUserCmdMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/MuteUserCmdMsgHdlr.scala @@ -2,6 +2,7 @@ package org.bigbluebutton.core.apps.users import org.bigbluebutton.common2.msgs.MuteUserCmdMsg import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } +import org.bigbluebutton.core.apps.voice.VoiceApp import org.bigbluebutton.core.models.{ Roles, Users2x, VoiceUsers } import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } import org.bigbluebutton.core2.MeetingStatus2x @@ -51,13 +52,12 @@ trait MuteUserCmdMsgHdlr extends RightsManagementTrait { } else { if (u.muted != msg.body.mute) { log.info("Send mute user request. meetingId=" + meetingId + " userId=" + u.intId + " user=" + u) - val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg( - meetingId, - voiceConf, - u.voiceUserId, + VoiceApp.muteUserInVoiceConf( + liveMeeting, + outGW, + u.intId, msg.body.mute ) - outGW.send(event) } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RegisterUserReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RegisterUserReqMsgHdlr.scala index b3a96abd82..5b5546a77d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RegisterUserReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/RegisterUserReqMsgHdlr.scala @@ -30,6 +30,7 @@ trait RegisterUserReqMsgHdlr { if (liveMeeting.props.usersProp.maxUserConcurrentAccesses > 0) { val userConcurrentAccesses = RegisteredUsers.findAllWithExternUserId(regUser.externId, liveMeeting.registeredUsers) .filter(u => !u.loggedOut) + .filter(u => !u.ejected) .sortWith((u1, u2) => u1.registeredOn > u2.registeredOn) //Remove older first val userAvailableSlots = liveMeeting.props.usersProp.maxUserConcurrentAccesses - userConcurrentAccesses.length @@ -46,9 +47,6 @@ trait RegisterUserReqMsgHdlr { val reason = "user ejected because of duplicate external userid" UsersApp.ejectUserFromMeeting(outGW, liveMeeting, userToRemove.id, SystemUser.ID, reason, EjectReasonCode.DUPLICATE_USER, ban = false) - // send a system message to force disconnection - Sender.sendDisconnectClientSysMsg(meetingId, userToRemove.id, SystemUser.ID, EjectReasonCode.DUPLICATE_USER, outGW) - // Force reconnection with graphql to refresh permissions Sender.sendForceUserGraphqlReconnectionSysMsg(liveMeeting.props.meetingProp.intId, userToRemove.id, userToRemove.sessionToken, EjectReasonCode.DUPLICATE_USER, outGW) } @@ -61,8 +59,8 @@ trait RegisterUserReqMsgHdlr { val regUser = RegisteredUsers.create(liveMeeting.props.meetingProp.intId, msg.body.intUserId, msg.body.extUserId, msg.body.name, msg.body.role, msg.body.authToken, msg.body.sessionToken, - msg.body.avatarURL, ColorPicker.nextColor(liveMeeting.props.meetingProp.intId), msg.body.guest, msg.body.authed, - guestStatus, msg.body.excludeFromDashboard, msg.body.enforceLayout, msg.body.customParameters, false) + msg.body.avatarURL, msg.body.webcamBackgroundURL, ColorPicker.nextColor(liveMeeting.props.meetingProp.intId), msg.body.guest, msg.body.authed, + guestStatus, msg.body.excludeFromDashboard, msg.body.enforceLayout, msg.body.userMetadata, false) checkUserConcurrentAccesses(regUser) RegisteredUsers.add(liveMeeting.registeredUsers, regUser, liveMeeting.props.meetingProp.intId) @@ -94,7 +92,7 @@ trait RegisterUserReqMsgHdlr { val g = GuestApprovedVO(regUser.id, GuestStatus.ALLOW) UsersApp.approveOrRejectGuest(liveMeeting, outGW, g, SystemUser.ID) case GuestStatus.WAIT => - val guest = GuestWaiting(regUser.id, regUser.name, regUser.role, regUser.guest, regUser.avatarURL, regUser.color, regUser.authed, regUser.registeredOn) + val guest = GuestWaiting(regUser.id, regUser.name, regUser.role, regUser.guest, regUser.avatarURL, regUser.webcamBackgroundURL, regUser.color, regUser.authed, regUser.registeredOn) addGuestToWaitingForApproval(guest, liveMeeting.guestsWaiting) notifyModeratorsOfGuestWaiting(Vector(guest), liveMeeting.users2x, liveMeeting.props.meetingProp.intId) val notifyEvent = MsgBuilder.buildNotifyRoleInMeetingEvtMsg( diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SendRecordingTimerInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SendRecordingTimerInternalMsgHdlr.scala deleted file mode 100755 index 96f8ce8aee..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SendRecordingTimerInternalMsgHdlr.scala +++ /dev/null @@ -1,43 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.api.SendRecordingTimerInternalMsg -import org.bigbluebutton.core.domain.MeetingState2x -import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } -import org.bigbluebutton.core.util.TimeUtil -import org.bigbluebutton.core2.MeetingStatus2x - -trait SendRecordingTimerInternalMsgHdlr { - this: UsersApp => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleSendRecordingTimerInternalMsg(msg: SendRecordingTimerInternalMsg, state: MeetingState2x): MeetingState2x = { - def buildUpdateRecordingTimerEvtMsg(meetingId: String, recordingTime: Long): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used") - val envelope = BbbCoreEnvelope(UpdateRecordingTimerEvtMsg.NAME, routing) - val body = UpdateRecordingTimerEvtMsgBody(recordingTime) - val header = BbbClientMsgHeader(UpdateRecordingTimerEvtMsg.NAME, meetingId, "not-used") - val event = UpdateRecordingTimerEvtMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - - var newDuration = 0L - if (MeetingStatus2x.isRecording(liveMeeting.status)) { - newDuration = TimeUtil.timeNowInMs() - val tracker = state.recordingTracker.udpateCurrentDuration(newDuration) - - val recordingTime = TimeUtil.millisToSeconds(tracker.recordingDuration()) - - val event = buildUpdateRecordingTimerEvtMsg(liveMeeting.props.meetingProp.intId, recordingTime) - outGW.send(event) - - state.update(tracker) - } else { - state - } - - } -} \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala index b592d373f2..2e9e5f51ba 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetRecordingStatusCmdMsgHdlr.scala @@ -5,8 +5,6 @@ import org.bigbluebutton.core.domain.MeetingState2x import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } import org.bigbluebutton.core2.MeetingStatus2x import org.bigbluebutton.core.util.TimeUtil -import org.bigbluebutton.core.bus.BigBlueButtonEvent -import org.bigbluebutton.core.api.SendRecordingTimerInternalMsg import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } import org.bigbluebutton.core2.message.senders.MsgBuilder import org.bigbluebutton.core.apps.voice.VoiceApp @@ -101,7 +99,7 @@ trait SetRecordingStatusCmdMsgHdlr extends RightsManagementTrait { val tracker = state.recordingTracker.pauseTimer(TimeUtil.timeNowInMs()) newState = state.update(tracker) } - eventBus.publish(BigBlueButtonEvent(liveMeeting.props.meetingProp.intId, SendRecordingTimerInternalMsg(liveMeeting.props.meetingProp.intId))) + newState } else { state diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserCaptionLocaleMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserCaptionLocaleMsgHdlr.scala new file mode 100644 index 0000000000..2eafd40033 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserCaptionLocaleMsgHdlr.scala @@ -0,0 +1,39 @@ +package org.bigbluebutton.core.apps.users + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.apps.RightsManagementTrait +import org.bigbluebutton.core.models.{ UserState, Users2x } +import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } + +trait SetUserCaptionLocaleMsgHdlr extends RightsManagementTrait { + this: UsersApp => + + val liveMeeting: LiveMeeting + val outGW: OutMsgRouter + + def handleSetUserCaptionLocaleReqMsg(msg: SetUserCaptionLocaleReqMsg): Unit = { + log.info("handleSetUserCaptionLocaleReqMsg: locale={} provider={} userId={}", msg.body.locale, msg.body.provider, msg.header.userId) + + def broadcastUserCaptionLocaleChanged(user: UserState, locale: String, provider: String): Unit = { + val routingChange = Routing.addMsgToClientRouting( + MessageTypes.BROADCAST_TO_MEETING, + liveMeeting.props.meetingProp.intId, user.intId + ) + val envelopeChange = BbbCoreEnvelope(UserCaptionLocaleChangedEvtMsg.NAME, routingChange) + val headerChange = BbbClientMsgHeader(UserCaptionLocaleChangedEvtMsg.NAME, liveMeeting.props.meetingProp.intId, user.intId) + + val bodyChange = UserCaptionLocaleChangedEvtMsgBody(locale, provider) + val eventChange = UserCaptionLocaleChangedEvtMsg(headerChange, bodyChange) + val msgEventChange = BbbCommonEnvCoreMsg(envelopeChange, eventChange) + outGW.send(msgEventChange) + } + + for { + user <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId) + } yield { + Users2x.setUserCaptionLocale(liveMeeting.users2x, msg.header.userId, msg.body.locale) + broadcastUserCaptionLocaleChanged(user, msg.body.locale, msg.body.provider) + } + + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserClientSettingsReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserClientSettingsReqMsgHdlr.scala new file mode 100644 index 0000000000..d21403392a --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserClientSettingsReqMsgHdlr.scala @@ -0,0 +1,22 @@ +package org.bigbluebutton.core.apps.users + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.apps.RightsManagementTrait +import org.bigbluebutton.core.db.{ JsonUtils, UserClientSettingsDAO, UserStateDAO } +import org.bigbluebutton.core.models.Users2x +import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } + +trait SetUserClientSettingsReqMsgHdlr extends RightsManagementTrait { + this: UsersApp => + + val liveMeeting: LiveMeeting + val outGW: OutMsgRouter + + def handleSetUserClientSettingsReqMsg(msg: SetUserClientSettingsReqMsg): Unit = { + for { + user <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId) + } yield { + UserClientSettingsDAO.insertOrUpdate(liveMeeting.props.meetingProp.intId, user.intId, JsonUtils.mapToJson(msg.body.userClientSettingsJson)) + } + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserEchoTestRunningReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserEchoTestRunningReqMsgHdlr.scala new file mode 100644 index 0000000000..093ec34203 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserEchoTestRunningReqMsgHdlr.scala @@ -0,0 +1,22 @@ +package org.bigbluebutton.core.apps.users + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.apps.RightsManagementTrait +import org.bigbluebutton.core.db.UserStateDAO +import org.bigbluebutton.core.models.Users2x +import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } + +trait SetUserEchoTestRunningReqMsgHdlr extends RightsManagementTrait { + this: UsersApp => + + val liveMeeting: LiveMeeting + val outGW: OutMsgRouter + + def handleSetUserEchoTestRunningReqMsg(msg: SetUserEchoTestRunningReqMsg): Unit = { + for { + user <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId) + } yield { + UserStateDAO.updateEchoTestRunningAt(liveMeeting.props.meetingProp.intId, user.intId) + } + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserSpeechLocaleMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserSpeechLocaleMsgHdlr.scala index 212ab2e548..fc47ff7b93 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserSpeechLocaleMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserSpeechLocaleMsgHdlr.scala @@ -4,6 +4,7 @@ import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.models.{ UserState, Users2x } import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } +import org.bigbluebutton.core.db.{ CaptionLocaleDAO, CaptionTypes } import org.bigbluebutton.core.domain.MeetingState2x trait SetUserSpeechLocaleMsgHdlr extends RightsManagementTrait { @@ -34,6 +35,12 @@ trait SetUserSpeechLocaleMsgHdlr extends RightsManagementTrait { } yield { var changeLocale: Option[UserState] = None; changeLocale = Users2x.setUserSpeechLocale(liveMeeting.users2x, msg.header.userId, msg.body.locale) + + // Add new CaptionLocale + CaptionLocaleDAO.insertOrUpdateCaptionLocale( + liveMeeting.props.meetingProp.intId, + msg.body.locale, CaptionTypes.AUDIO_TRANSCRIPTION, msg.header.userId + ) broadcastUserSpeechLocaleChanged(user, msg.body.locale, msg.body.provider) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserSpeechOptionsMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserSpeechOptionsMsgHdlr.scala index b179506a94..7ce454d9b9 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserSpeechOptionsMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SetUserSpeechOptionsMsgHdlr.scala @@ -32,8 +32,6 @@ trait SetUserSpeechOptionsMsgHdlr extends RightsManagementTrait { for { user <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId) } yield { - var changeLocale: Option[UserState] = None; - //changeLocale = Users2x.setUserSpeechLocale(liveMeeting.users2x, msg.header.userId, msg.body.locale) broadcastUserSpeechOptionsChanged(user, msg.body.partialUtterances, msg.body.minUtteranceLength) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SyncGetUsersMeetingRespMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SyncGetUsersMeetingRespMsgHdlr.scala deleted file mode 100755 index ec9c0e9e44..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/SyncGetUsersMeetingRespMsgHdlr.scala +++ /dev/null @@ -1,41 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.models.Users2x -import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } - -trait SyncGetUsersMeetingRespMsgHdlr { - this: UsersApp => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleSyncGetUsersMeetingRespMsg(): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp") - val envelope = BbbCoreEnvelope(SyncGetUsersMeetingRespMsg.NAME, routing) - val header = BbbClientMsgHeader(SyncGetUsersMeetingRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp") - - val users = Users2x.findAll(liveMeeting.users2x) - val webUsers = users.map { u => - WebUser( - intId = u.intId, - extId = u.extId, - name = u.name, - role = u.role, - guest = u.guest, - authed = u.authed, - guestStatus = u.guestStatus, - emoji = u.emoji, - locked = u.locked, - presenter = u.presenter, - avatar = u.avatar, - clientType = u.clientType - ) - } - - val body = SyncGetUsersMeetingRespMsgBody(webUsers) - val event = SyncGetUsersMeetingRespMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - outGW.send(msgEvent) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectionAliveReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectionAliveReqMsgHdlr.scala index e37b1492b2..b352d0e6ba 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectionAliveReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserConnectionAliveReqMsgHdlr.scala @@ -1,6 +1,6 @@ package org.bigbluebutton.core.apps.users -import org.bigbluebutton.ClientSettings.{ getConfigPropertyValueByPathAsListOfIntOrElse, getConfigPropertyValueByPathAsListOfStringOrElse } +import org.bigbluebutton.ClientSettings.getConfigPropertyValueByPathAsIntOrElse import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.apps.RightsManagementTrait import org.bigbluebutton.core.db.UserConnectionStatusDAO @@ -31,25 +31,17 @@ trait UserConnectionAliveReqMsgHdlr extends RightsManagementTrait { } def getLevelFromRtt(networkRttInMs: Double): String = { - val levelOptions = getConfigPropertyValueByPathAsListOfStringOrElse( - liveMeeting.clientSettings, - "public.stats.level", - List("warning", "danger", "critical") - ) + val clientSettings = liveMeeting.clientSettings + val warningValue = getConfigPropertyValueByPathAsIntOrElse(clientSettings, "public.stats.rtt.warning", 500) + val dangerValue = getConfigPropertyValueByPathAsIntOrElse(clientSettings, "public.stats.rtt.danger", 1000) + val criticalValue = getConfigPropertyValueByPathAsIntOrElse(clientSettings, "public.stats.rtt.critical", 2000) - val rttOptions = getConfigPropertyValueByPathAsListOfIntOrElse( - liveMeeting.clientSettings, - "public.stats.rtt", - List(500, 1000, 2000) - ) - - val statusRttXLevel = levelOptions.zip(rttOptions).reverse - - val statusFound = statusRttXLevel.collectFirst { - case (level, rtt) if networkRttInMs > rtt => level + networkRttInMs match { + case rtt if rtt > criticalValue => "critical" + case rtt if rtt > dangerValue => "danger" + case rtt if rtt > warningValue => "warning" + case _ => "normal" } - - statusFound.getOrElse("normal") } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserEstablishedGraphqlConnectionInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserEstablishedGraphqlConnectionInternalMsgHdlr.scala index 19942397fe..25328da510 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserEstablishedGraphqlConnectionInternalMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserEstablishedGraphqlConnectionInternalMsgHdlr.scala @@ -1,8 +1,9 @@ package org.bigbluebutton.core.apps.users +import org.bigbluebutton.common2.msgs.{ BbbClientMsgHeader, BbbCommonEnvCoreMsg, BbbCoreEnvelope, MessageTypes, Routing, UserMobileFlagChangedEvtMsg, UserMobileFlagChangedEvtMsgBody } import org.bigbluebutton.core.api.UserEstablishedGraphqlConnectionInternalMsg import org.bigbluebutton.core.domain.MeetingState2x -import org.bigbluebutton.core.models.Users2x +import org.bigbluebutton.core.models.{ RegisteredUsers, UserState, Users2x } import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting, MeetingActor, OutMsgRouter } trait UserEstablishedGraphqlConnectionInternalMsgHdlr extends HandlerHelpers { @@ -12,18 +13,57 @@ trait UserEstablishedGraphqlConnectionInternalMsgHdlr extends HandlerHelpers { val outGW: OutMsgRouter def handleUserEstablishedGraphqlConnectionInternalMsg(msg: UserEstablishedGraphqlConnectionInternalMsg, state: MeetingState2x): MeetingState2x = { - log.info("Received user established a graphql connection. user {} meetingId={}", msg.userId, liveMeeting.props.meetingProp.intId) + log.info("Received user established a graphql connection. msg={} meetingId={}", msg, liveMeeting.props.meetingProp.intId) + + for { + regUser <- RegisteredUsers.findWithUserId(msg.userId, liveMeeting.registeredUsers) + } yield { + RegisteredUsers.updateUserConnectedToGraphql(liveMeeting.registeredUsers, regUser, graphqlConnected = true) + } + Users2x.findWithIntId(liveMeeting.users2x, msg.userId) match { - case Some(reconnectingUser) => - if (reconnectingUser.userLeftFlag.left) { + case Some(connectingUser) => + var userNewState = connectingUser + + if (connectingUser.userLeftFlag.left) { log.info("Resetting flag that user left meeting. user {}", msg.userId) sendUserLeftFlagUpdatedEvtMsg(outGW, liveMeeting, msg.userId, leftFlag = false) - Users2x.resetUserLeftFlag(liveMeeting.users2x, msg.userId) + for { + userUpdated <- Users2x.resetUserLeftFlag(liveMeeting.users2x, msg.userId) + } yield { + userNewState = userUpdated + } } + + //isMobile and clientType are set on join, but if it is a reconnection join is not necessary + //so it need to be set here + if (connectingUser.mobile != msg.isMobile) { + userNewState = Users2x.setMobile(liveMeeting.users2x, userNewState) + broadcastUserMobileChanged(userNewState, msg.isMobile) + } + + if (connectingUser.clientType != msg.clientType) { + userNewState = Users2x.setClientType(liveMeeting.users2x, userNewState, msg.clientType) + } + state case None => state } } -} + def broadcastUserMobileChanged(user: UserState, mobile: Boolean): Unit = { + val routingChange = Routing.addMsgToClientRouting( + MessageTypes.BROADCAST_TO_MEETING, + liveMeeting.props.meetingProp.intId, user.intId + ) + val envelopeChange = BbbCoreEnvelope(UserMobileFlagChangedEvtMsg.NAME, routingChange) + val headerChange = BbbClientMsgHeader(UserMobileFlagChangedEvtMsg.NAME, liveMeeting.props.meetingProp.intId, + user.intId) + + val bodyChange = UserMobileFlagChangedEvtMsgBody(user.intId, mobile) + val eventChange = UserMobileFlagChangedEvtMsg(headerChange, bodyChange) + val msgEventChange = BbbCommonEnvCoreMsg(envelopeChange, eventChange) + outGW.send(msgEventChange) + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingAfterReconnectReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingAfterReconnectReqMsgHdlr.scala deleted file mode 100755 index f5c8558a54..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingAfterReconnectReqMsgHdlr.scala +++ /dev/null @@ -1,37 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs.UserJoinMeetingAfterReconnectReqMsg -import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers -import org.bigbluebutton.core.apps.voice.UserJoinedVoiceConfEvtMsgHdlr -import org.bigbluebutton.core.domain.MeetingState2x -import org.bigbluebutton.core.models.Users2x -import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting, MeetingActor, OutMsgRouter } - -trait UserJoinMeetingAfterReconnectReqMsgHdlr extends HandlerHelpers with UserJoinedVoiceConfEvtMsgHdlr { - this: MeetingActor => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleUserJoinMeetingAfterReconnectReqMsg(msg: UserJoinMeetingAfterReconnectReqMsg, state: MeetingState2x): MeetingState2x = { - log.info("Received user joined after reconnecting. user {} meetingId={}", msg.body.userId, msg.header.meetingId) - Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId) match { - case Some(reconnectingUser) => - if (reconnectingUser.userLeftFlag.left) { - log.info("Resetting flag that user left meeting. user {}", msg.body.userId) - // User has reconnected. Just reset it's flag. ralam Oct 23, 2018 - sendUserLeftFlagUpdatedEvtMsg(outGW, liveMeeting, msg.body.userId, leftFlag = false) - Users2x.resetUserLeftFlag(liveMeeting.users2x, msg.body.userId) - } - state - case None => - val newState = userJoinMeeting(outGW, msg.body.authToken, msg.body.clientType, liveMeeting, state) - if (liveMeeting.props.meetingProp.isBreakout) { - BreakoutHdlrHelpers.updateParentMeetingWithUsers(liveMeeting, eventBus) - } - newState - } - } - -} - diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingReqMsgHdlr.scala index 80278fa920..11d15092e0 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserJoinMeetingReqMsgHdlr.scala @@ -34,6 +34,7 @@ trait UserJoinMeetingReqMsgHdlr extends HandlerHelpers { val validationResult = for { _ <- checkIfUserGuestStatusIsAllowed(user) _ <- checkIfUserIsBanned(user) + _ <- checkIfUserEjected(user) _ <- checkIfUserLoggedOut(user) _ <- validateMaxParticipants(user) } yield user @@ -46,7 +47,7 @@ trait UserJoinMeetingReqMsgHdlr extends HandlerHelpers { } private def handleSuccessfulUserJoin(msg: UserJoinMeetingReqMsg, regUser: RegisteredUser) = { - val newState = userJoinMeeting(outGW, msg.body.authToken, msg.body.clientType, liveMeeting, state) + val newState = userJoinMeeting(outGW, msg.body.authToken, msg.body.clientType, msg.body.clientIsMobile, liveMeeting, state) updateParentMeetingWithNewListOfUsers() notifyPreviousUsersWithSameExtId(regUser) clearCachedVoiceUser(regUser) @@ -104,6 +105,14 @@ trait UserJoinMeetingReqMsgHdlr extends HandlerHelpers { } } + private def checkIfUserEjected(user: RegisteredUser): Either[(String, String), Unit] = { + if (user.ejected) { + Left(("User had ejected", EjectReasonCode.EJECT_USER)) + } else { + Right(()) + } + } + private def checkIfUserLoggedOut(user: RegisteredUser): Either[(String, String), Unit] = { if (user.loggedOut) { Left(("User had logged out", EjectReasonCode.USER_LOGGED_OUT)) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserLeaveReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserLeaveReqMsgHdlr.scala index 9e64c6e40e..25d551908f 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserLeaveReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserLeaveReqMsgHdlr.scala @@ -19,6 +19,12 @@ trait UserLeaveReqMsgHdlr extends HandlerHelpers { def handleUserClosedAllGraphqlConnectionsInternalMsg(msg: UserClosedAllGraphqlConnectionsInternalMsg, state: MeetingState2x): MeetingState2x = { log.info("Received user closed all graphql connections. user {} meetingId={}", msg.userId, liveMeeting.props.meetingProp.intId) + for { + regUser <- RegisteredUsers.findWithUserId(msg.userId, liveMeeting.registeredUsers) + } yield { + RegisteredUsers.updateUserConnectedToGraphql(liveMeeting.registeredUsers, regUser, graphqlConnected = false) + } + handleUserLeaveReq(msg.userId, liveMeeting.props.meetingProp.intId, loggedOut = false, state) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserReactionTimeExpiredCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserReactionTimeExpiredCmdMsgHdlr.scala deleted file mode 100644 index c73ac924a7..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UserReactionTimeExpiredCmdMsgHdlr.scala +++ /dev/null @@ -1,19 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.models.Users2x -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } -import org.bigbluebutton.core.apps.{ RightsManagementTrait } - -trait UserReactionTimeExpiredCmdMsgHdlr extends RightsManagementTrait { - this: BaseMeetingActor => - - val liveMeeting: LiveMeeting - - def handleUserReactionTimeExpiredCmdMsg(msg: UserReactionTimeExpiredCmdMsg) { - val isNodeUser = msg.header.userId.equals("nodeJSapp") - if (isNodeUser) { - Users2x.setReactionEmoji(liveMeeting.users2x, msg.body.userId, "none", 0) - } - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala index 8503e3f9e0..5b948066b7 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp.scala @@ -4,12 +4,12 @@ import org.apache.pekko.actor.ActorContext import org.apache.pekko.event.Logging import org.bigbluebutton.Boot.eventBus import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.api.{SetPresenterInDefaultPodInternalMsg} +import org.bigbluebutton.core.api.SetPresenterInDefaultPodInternalMsg import org.bigbluebutton.core.apps.ExternalVideoModel import org.bigbluebutton.core.bus.{BigBlueButtonEvent, InternalEventBus} import org.bigbluebutton.core.models._ import org.bigbluebutton.core.running.{LiveMeeting, OutMsgRouter} -import org.bigbluebutton.core2.message.senders.{MsgBuilder} +import org.bigbluebutton.core2.message.senders.{MsgBuilder, Sender} import org.bigbluebutton.core.apps.screenshare.ScreenshareApp2x import org.bigbluebutton.core.db.UserStateDAO @@ -31,7 +31,7 @@ object UsersApp { u <- RegisteredUsers.findWithUserId(userId, liveMeeting.registeredUsers) } yield { - RegisteredUsers.eject(u.id, liveMeeting.registeredUsers, false) + RegisteredUsers.eject(u.id, liveMeeting.registeredUsers, ban = false) val event = MsgBuilder.buildGuestWaitingLeftEvtMsg(liveMeeting.props.meetingProp.intId, u.id) outGW.send(event) @@ -71,6 +71,13 @@ object UsersApp { } yield { sendPresenterAssigned(outGW, meetingId, newPresenter.intId, newPresenter.name, newPresenter.intId) sendPresenterInPodReq(meetingId, newPresenter.intId) + + // Force reconnection with graphql to refresh permissions + for { + regUser <- RegisteredUsers.findWithUserId(newPresenter.intId, liveMeeting.registeredUsers) + } yield { + Sender.sendForceUserGraphqlReconnectionSysMsg(liveMeeting.props.meetingProp.intId, regUser.id, regUser.sessionToken, "role_changed", outGW) + } } } @@ -153,21 +160,20 @@ class UsersApp( val eventBus: InternalEventBus )(implicit val context: ActorContext) - extends ValidateAuthTokenReqMsgHdlr - with GetUsersMeetingReqMsgHdlr - with RegisterUserReqMsgHdlr + extends RegisterUserReqMsgHdlr + with GetUserApiMsgHdlr with ChangeUserRoleCmdMsgHdlr with SetUserSpeechLocaleMsgHdlr + with SetUserCaptionLocaleMsgHdlr + with SetUserClientSettingsReqMsgHdlr + with SetUserEchoTestRunningReqMsgHdlr with SetUserSpeechOptionsMsgHdlr - with SyncGetUsersMeetingRespMsgHdlr with LogoutAndEndMeetingCmdMsgHdlr with SetRecordingStatusCmdMsgHdlr with RecordAndClearPreviousMarkersCmdMsgHdlr - with SendRecordingTimerInternalMsgHdlr with GetRecordingStatusReqMsgHdlr with AssignPresenterReqMsgHdlr with ChangeUserPinStateReqMsgHdlr - with ChangeUserMobileFlagReqMsgHdlr with UserConnectionAliveReqMsgHdlr with ChangeUserReactionEmojiReqMsgHdlr with ChangeUserRaiseHandReqMsgHdlr diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp2x.scala index f2a4fe4f53..26d796f656 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/UsersApp2x.scala @@ -6,11 +6,7 @@ trait UsersApp2x extends UserLeaveReqMsgHdlr with LockUserInMeetingCmdMsgHdlr with LockUsersInMeetingCmdMsgHdlr - with GetLockSettingsReqMsgHdlr - with ChangeUserEmojiCmdMsgHdlr - with ClearAllUsersEmojiCmdMsgHdlr - with ClearAllUsersReactionCmdMsgHdlr - with UserReactionTimeExpiredCmdMsgHdlr { + with ClearAllUsersReactionCmdMsgHdlr { this: MeetingActor => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ValidateAuthTokenReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ValidateAuthTokenReqMsgHdlr.scala deleted file mode 100755 index e2d063c19f..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/ValidateAuthTokenReqMsgHdlr.scala +++ /dev/null @@ -1,117 +0,0 @@ -package org.bigbluebutton.core.apps.users - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.bus.InternalEventBus -import org.bigbluebutton.core.db.UserDAO -import org.bigbluebutton.core.domain.MeetingState2x -import org.bigbluebutton.core.models._ -import org.bigbluebutton.core.running.{ HandlerHelpers, LiveMeeting, OutMsgRouter } -import org.bigbluebutton.core2.message.senders.MsgBuilder - -trait ValidateAuthTokenReqMsgHdlr extends HandlerHelpers { - this: UsersApp => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - val eventBus: InternalEventBus - - def handleValidateAuthTokenReqMsg(msg: ValidateAuthTokenReqMsg, state: MeetingState2x): MeetingState2x = { - log.debug(s"Received ValidateAuthTokenReqMsg msg $msg") - - val regUser = RegisteredUsers.getRegisteredUserWithToken(msg.body.authToken, msg.body.userId, liveMeeting.registeredUsers) - log.info(s"Number of registered users [${RegisteredUsers.numRegisteredUsers(liveMeeting.registeredUsers)}]") - - regUser.fold { - sendFailedValidateAuthTokenRespMsg(msg, "Invalid auth token.", EjectReasonCode.VALIDATE_TOKEN) - } { user => - val validationResult = for { - _ <- checkIfUserGuestStatusIsAllowed(user) - _ <- checkIfUserIsBanned(user) - _ <- checkIfUserLoggedOut(user) - _ <- validateMaxParticipants(user) - } yield user - - validationResult.fold( - reason => sendFailedValidateAuthTokenRespMsg(msg, reason._1, reason._2), - validUser => sendSuccessfulValidateAuthTokenRespMsg(validUser) - ) - } - - state - } - - private def validateMaxParticipants(user: RegisteredUser): Either[(String, String), Unit] = { - if (liveMeeting.props.usersProp.maxUsers > 0 && - RegisteredUsers.numUniqueJoinedUsers(liveMeeting.registeredUsers) >= liveMeeting.props.usersProp.maxUsers && - RegisteredUsers.checkUserExtIdHasJoined(user.externId, liveMeeting.registeredUsers) == false) { - Left(("The maximum number of participants allowed for this meeting has been reached.", EjectReasonCode.MAX_PARTICIPANTS)) - } else { - Right(()) - } - } - - private def checkIfUserGuestStatusIsAllowed(user: RegisteredUser): Either[(String, String), Unit] = { - if (user.guestStatus != GuestStatus.ALLOW) { - Left(("User is not allowed to join", EjectReasonCode.PERMISSION_FAILED)) - } else { - Right(()) - } - } - - private def checkIfUserIsBanned(user: RegisteredUser): Either[(String, String), Unit] = { - if (user.banned) { - Left(("Banned user rejoining", EjectReasonCode.BANNED_USER_REJOINING)) - } else { - Right(()) - } - } - - private def checkIfUserLoggedOut(user: RegisteredUser): Either[(String, String), Unit] = { - if (user.loggedOut) { - Left(("User had logged out", EjectReasonCode.USER_LOGGED_OUT)) - } else { - Right(()) - } - } - - private def sendFailedValidateAuthTokenRespMsg(msg: ValidateAuthTokenReqMsg, failReason: String, failReasonCode: String) = { - UserDAO.updateJoinError(msg.header.meetingId, msg.body.userId, failReasonCode, failReason) - - val event = MsgBuilder.buildValidateAuthTokenRespMsg(liveMeeting.props.meetingProp.intId, msg.header.userId, msg.body.authToken, false, false, 0, - 0, failReasonCode, failReason) - outGW.send(event) - } - - def sendSuccessfulValidateAuthTokenRespMsg(user: RegisteredUser) = { - val meetingId = liveMeeting.props.meetingProp.intId - val updatedUser = RegisteredUsers.updateUserLastAuthTokenValidated(liveMeeting.registeredUsers, user) - - val event = MsgBuilder.buildValidateAuthTokenRespMsg(meetingId, updatedUser.id, updatedUser.authToken, true, false, updatedUser.registeredOn, - updatedUser.lastAuthTokenValidatedOn, EjectReasonCode.NOT_EJECT, "User not ejected") - outGW.send(event) - } - - def sendAllUsersInMeeting(requesterId: String): Unit = { - val meetingId = liveMeeting.props.meetingProp.intId - val users = Users2x.findAll(liveMeeting.users2x) - val webUsers = users.map { u => - WebUser(intId = u.intId, extId = u.extId, name = u.name, role = u.role, - guest = u.guest, authed = u.authed, guestStatus = u.guestStatus, emoji = u.emoji, - locked = u.locked, presenter = u.presenter, avatar = u.avatar, clientType = u.clientType) - } - - val event = MsgBuilder.buildGetUsersMeetingRespMsg(meetingId, requesterId, webUsers) - outGW.send(event) - } - - def sendAllVoiceUsersInMeeting(requesterId: String, voiceUsers: VoiceUsers, meetingId: String): Unit = { - val vu = VoiceUsers.findAll(voiceUsers).map { u => - VoiceConfUser(intId = u.intId, voiceUserId = u.voiceUserId, callingWith = u.callingWith, callerName = u.callerName, - callerNum = u.callerNum, color = u.color, muted = u.muted, talking = u.talking, listenOnly = u.listenOnly) - } - - val event = MsgBuilder.buildGetVoiceUsersMeetingRespMsg(meetingId, requesterId, vu) - outGW.send(event) - } - -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/GetMicrophonePermissionReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/GetMicrophonePermissionReqMsgHdlr.scala index ff78e1859f..f1bd35cd8c 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/GetMicrophonePermissionReqMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/GetMicrophonePermissionReqMsgHdlr.scala @@ -2,6 +2,7 @@ package org.bigbluebutton.core.apps.voice import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter } +import org.bigbluebutton.core2.MeetingStatus2x trait GetMicrophonePermissionReqMsgHdlr { this: MeetingActor => @@ -16,7 +17,8 @@ trait GetMicrophonePermissionReqMsgHdlr { voiceConf: String, userId: String, sfuSessionId: String, - allowed: Boolean + allowed: Boolean, + muteOnStart: Boolean ): Unit = { val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId) val envelope = BbbCoreEnvelope(GetMicrophonePermissionRespMsg.NAME, routing) @@ -26,7 +28,8 @@ trait GetMicrophonePermissionReqMsgHdlr { voiceConf, userId, sfuSessionId, - allowed + allowed, + muteOnStart ) val event = GetMicrophonePermissionRespMsg(header, body) val eventMsg = BbbCommonEnvCoreMsg(envelope, event) @@ -41,13 +44,18 @@ trait GetMicrophonePermissionReqMsgHdlr { msg.body.voiceConf, msg.body.callerIdNum ) + // Lock settings should only define whether the user starts muted or not. + // It must not prevent users from joining audio. + val locked = VoiceHdlrHelpers.isMicrophoneSharingLocked(liveMeeting, msg.body.userId) + val muteOnStart = MeetingStatus2x.isMeetingMuted(liveMeeting.status) || locked broadcastEvent( liveMeeting.props.meetingProp.intId, liveMeeting.props.voiceProp.voiceConf, msg.body.userId, msg.body.sfuSessionId, - allowed + allowed, + muteOnStart ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/ListenOnlyModeToggledInSfuEvtMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/ListenOnlyModeToggledInSfuEvtMsgHdlr.scala index 0b16a39a61..b2e137c1e6 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/ListenOnlyModeToggledInSfuEvtMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/ListenOnlyModeToggledInSfuEvtMsgHdlr.scala @@ -12,11 +12,34 @@ trait ListenOnlyModeToggledInSfuEvtMsgHdlr { def handleListenOnlyModeToggledInSfuEvtMsg(msg: ListenOnlyModeToggledInSfuEvtMsg): Unit = { for { - vu <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.body.userId) + vu <- VoiceUsers.findWithIntIdAndCallerNum( + liveMeeting.voiceUsers, + msg.body.userId, + msg.body.callerNum + ) } yield { - VoiceApp.holdChannelInVoiceConf( + // Do not execute if the command is asking for the channel to be HELD + // and the channel is already HELD. This is an edge case with the uuid_hold + // command being used through FSESL or fsapi where holding only works via + // the uuid_hold subcommand, which may cause the channel to be the + // opposite of what we want. + // The unhold (uuid_hold off) command is not affected by this, but we don't + // want to send it if the channel is already unheld. + if ((msg.body.enabled && !vu.hold) || !msg.body.enabled) { + VoiceApp.holdChannelInVoiceConf( + liveMeeting, + outGW, + vu.uuid, + msg.body.enabled + ) + } + + // If the channel is already in the desired state, just make sure + // any pending mute or unmute commands are sent. + VoiceApp.handleChannelHoldChanged( liveMeeting, outGW, + msg.body.userId, vu.uuid, msg.body.enabled ) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/RecordingFileSplitter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/RecordingFileSplitter.scala new file mode 100644 index 0000000000..d106c31257 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/RecordingFileSplitter.scala @@ -0,0 +1,76 @@ +package org.bigbluebutton.core.apps.voice + +import org.bigbluebutton.SystemConfiguration +import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter } +import org.bigbluebutton.core2.MeetingStatus2x +import org.bigbluebutton.core2.message.senders.MsgBuilder + +class RecordingFileSplitter( + val liveMeeting: LiveMeeting, + val outGW: OutMsgRouter, + val stream: String +) extends SystemConfiguration { + + var startRecTimer: java.util.Timer = null + var stopRecTimer: java.util.Timer = null + var currentStreamPath: String = stream + var previousStreamPath: String = stream + val lastPointPos = stream.lastIndexOf('.') + val pathWithoutExtension: String = stream.substring(0, lastPointPos) + val extension: String = stream.substring(lastPointPos, stream.length()) + + class RecordingFileSplitterStopTask extends java.util.TimerTask { + def run() { + val event = MsgBuilder.buildStopRecordingVoiceConfSysMsg( + liveMeeting.props.meetingProp.intId, + liveMeeting.props.voiceProp.voiceConf, + previousStreamPath + ) + outGW.send(event) + } + } + + class RecordingFileSplitterStartTask extends java.util.TimerTask { + var currentFileNumber: Int = 0 + + def run() { + val newStreamPath = pathWithoutExtension + "_" + String.valueOf(currentFileNumber) + extension; + MeetingStatus2x.voiceRecordingStart(liveMeeting.status, newStreamPath) + val event = MsgBuilder.buildStartRecordingVoiceConfSysMsg( + liveMeeting.props.meetingProp.intId, + liveMeeting.props.voiceProp.voiceConf, + newStreamPath + ) + outGW.send(event) + + if (currentStreamPath == stream) { + // first file, no previous one to stop + previousStreamPath = newStreamPath + } else { + previousStreamPath = currentStreamPath + // stop previous recording, wait 5 seconds to avoid interruptions + stopRecTimer = new java.util.Timer() + stopRecTimer.schedule(new RecordingFileSplitterStopTask(), 5000L) + } + + currentStreamPath = newStreamPath + currentFileNumber = currentFileNumber + 1 + } + } + + def stop() { + startRecTimer.cancel() + if (stopRecTimer != null) { + stopRecTimer.cancel() + } + } + + def start(): Unit = { + startRecTimer = new java.util.Timer() + startRecTimer.schedule( + new RecordingFileSplitterStartTask(), + 0L, //initial delay + voiceConfRecordFileSplitterIntervalInMinutes * 60000L //subsequent rate + ); + } +} \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/SyncGetVoiceUsersMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/SyncGetVoiceUsersMsgHdlr.scala deleted file mode 100644 index 88631d992f..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/SyncGetVoiceUsersMsgHdlr.scala +++ /dev/null @@ -1,34 +0,0 @@ -package org.bigbluebutton.core.apps.voice - -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting } -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.bus.MessageBus -import org.bigbluebutton.core.models.VoiceUsers -import org.bigbluebutton.core.domain.MeetingState2x - -trait SyncGetVoiceUsersMsgHdlr { - this: BaseMeetingActor => - - def handleSyncGetVoiceUsersMsg(state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus): MeetingState2x = { - - def buildSyncGetVoiceUsersRespMsg(): BbbCommonEnvCoreMsg = { - val voiceUsers = VoiceUsers.findAll(liveMeeting.voiceUsers).map { u => - VoiceConfUser(intId = u.intId, voiceUserId = u.voiceUserId, callingWith = u.callingWith, callerName = u.callerName, - callerNum = u.callerNum, color = u.color, muted = u.muted, talking = u.talking, listenOnly = u.listenOnly) - } - - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, "nodeJSapp") - val envelope = BbbCoreEnvelope(SyncGetVoiceUsersRespMsg.NAME, routing) - val header = BbbClientMsgHeader(SyncGetVoiceUsersRespMsg.NAME, liveMeeting.props.meetingProp.intId, "nodeJSapp") - val body = SyncGetVoiceUsersRespMsgBody(voiceUsers) - val event = SyncGetVoiceUsersRespMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - - val respMsg = buildSyncGetVoiceUsersRespMsg() - bus.outGW.send(respMsg) - - state - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala index 4779c5811b..ab150de266 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserJoinedVoiceConfEvtMsgHdlr.scala @@ -33,7 +33,7 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends SystemConfiguration { def registerUserInRegisteredUsers() = { val regUser = RegisteredUsers.create(liveMeeting.props.meetingProp.intId, msg.body.intId, msg.body.voiceUserId, - msg.body.callerIdName, Roles.VIEWER_ROLE, msg.body.intId, "", "", userColor, + msg.body.callerIdName, Roles.VIEWER_ROLE, msg.body.intId, "", "", "", userColor, true, true, GuestStatus.WAIT, true, "", Map(), false) RegisteredUsers.add(liveMeeting.registeredUsers, regUser, liveMeeting.props.meetingProp.intId) } @@ -48,7 +48,6 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends SystemConfiguration { guest = true, authed = true, guestStatus = GuestStatus.WAIT, - emoji = "none", reactionEmoji = "none", raiseHand = false, away = false, @@ -57,6 +56,7 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends SystemConfiguration { presenter = false, locked = MeetingStatus2x.getPermissions(liveMeeting.status).lockOnJoin, avatar = "", + webcamBackground = "", color = userColor, clientType = if (isDialInUser) "dial-in-user" else "", userLeftFlag = UserLeftFlag(false, 0) @@ -66,7 +66,7 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends SystemConfiguration { def registerUserAsGuest() = { if (GuestsWaiting.findWithIntId(liveMeeting.guestsWaiting, msg.body.intId) == None) { - val guest = GuestWaiting(msg.body.intId, msg.body.callerIdName, Roles.VIEWER_ROLE, true, "", userColor, true, System.currentTimeMillis()) + val guest = GuestWaiting(msg.body.intId, msg.body.callerIdName, Roles.VIEWER_ROLE, true, "", "", userColor, true, System.currentTimeMillis()) GuestsWaiting.add(liveMeeting.guestsWaiting, guest) notifyModeratorsOfGuestWaiting(guest, liveMeeting.users2x, liveMeeting.props.meetingProp.intId) @@ -112,14 +112,18 @@ trait UserJoinedVoiceConfEvtMsgHdlr extends SystemConfiguration { if (isDialInUser) { registerUserInRegisteredUsers() registerUserInUsers2x() - guestPolicy match { - case GuestPolicy(policy, setBy) => { - policy match { - case GuestPolicyType.ALWAYS_ACCEPT => letUserEnter() - case GuestPolicyType.ALWAYS_DENY => VoiceApp.removeUserFromVoiceConf(liveMeeting, outGW, msg.body.voiceUserId) - case GuestPolicyType.ASK_MODERATOR => registerUserAsGuest() + if (dialInEnforceGuestPolicy) { + guestPolicy match { + case GuestPolicy(policy, setBy) => { + policy match { + case GuestPolicyType.ALWAYS_ACCEPT => letUserEnter() + case GuestPolicyType.ALWAYS_DENY => VoiceApp.removeUserFromVoiceConf(liveMeeting, outGW, msg.body.voiceUserId) + case GuestPolicyType.ASK_MODERATOR => registerUserAsGuest() + } } } + } else { + letUserEnter() } } else { // Regular users reach this point after beeing diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserLeftVoiceConfEvtMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserLeftVoiceConfEvtMsgHdlr.scala index 5bc7ed7818..8875aa7963 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserLeftVoiceConfEvtMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/UserLeftVoiceConfEvtMsgHdlr.scala @@ -49,6 +49,10 @@ trait UserLeftVoiceConfEvtMsgHdlr { } yield { VoiceUsers.removeWithIntId(liveMeeting.voiceUsers, liveMeeting.props.meetingProp.intId, user.intId) broadcastEvent(user) + + if (!user.listenOnly) { + VoiceApp.enforceMuteOnStartThreshold(liveMeeting, outGW) + } } if (liveMeeting.props.meetingProp.isBreakout) { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala index 780c2968d8..81b28d315d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp.scala @@ -22,6 +22,7 @@ import scala.concurrent.duration._ object VoiceApp extends SystemConfiguration { // Key is userId var toggleListenOnlyTasks: Map[String, Cancellable] = Map() + var recordingFileSplitters: Map[String, RecordingFileSplitter] = Map() def genRecordPath( recordDir: String, @@ -45,6 +46,13 @@ object VoiceApp extends SystemConfiguration { } def stopRecordingVoiceConference(liveMeeting: LiveMeeting, outGW: OutMsgRouter): Unit = { + // stop file splitter + val voiceconf = liveMeeting.props.voiceProp.voiceConf + if (recordingFileSplitters.contains(voiceconf)) { + recordingFileSplitters(voiceconf).stop(); + recordingFileSplitters = recordingFileSplitters - (voiceconf) + } + val recStreams = MeetingStatus2x.getVoiceRecordingStreams(liveMeeting.status) recStreams foreach { rs => @@ -68,13 +76,24 @@ object VoiceApp extends SystemConfiguration { now, voiceConfRecordCodec ) - MeetingStatus2x.voiceRecordingStart(liveMeeting.status, recordFile) - val event = MsgBuilder.buildStartRecordingVoiceConfSysMsg( - liveMeeting.props.meetingProp.intId, - liveMeeting.props.voiceProp.voiceConf, - recordFile - ) - outGW.send(event) + if (voiceConfRecordEnableFileSplitter) { + val voiceconf = liveMeeting.props.voiceProp.voiceConf + if (recordingFileSplitters.contains(voiceconf)) { + recordingFileSplitters(voiceconf).stop(); + recordingFileSplitters = recordingFileSplitters - (voiceconf) + } + val fileSplitter = new RecordingFileSplitter(liveMeeting, outGW, recordFile) + recordingFileSplitters = recordingFileSplitters + (voiceconf -> fileSplitter) + fileSplitter.start() + } else { + MeetingStatus2x.voiceRecordingStart(liveMeeting.status, recordFile) + val event = MsgBuilder.buildStartRecordingVoiceConfSysMsg( + liveMeeting.props.meetingProp.intId, + liveMeeting.props.voiceProp.voiceConf, + recordFile + ) + outGW.send(event) + } } def broadcastUserMutedVoiceEvtMsg( @@ -133,13 +152,14 @@ object VoiceApp extends SystemConfiguration { liveMeeting, outGW, mutedUser.intId, + mutedUser.callerNum, muted, toggleListenOnlyAfterMuteTimer ) // If the user is muted or unmuted with an unheld channel, broadcast // the event right away. - // If the user is unmuted, but channel is held, we need to wait for the + // If the user is unmuted, but channel is held, we need to wait for the // channel to be active again to broadcast the event. See // VoiceApp.handleChannelHoldChanged for this second case. if (muted || (!muted && !mutedUser.hold)) { @@ -150,7 +170,6 @@ object VoiceApp extends SystemConfiguration { outGW ) } - } } @@ -261,7 +280,7 @@ object VoiceApp extends SystemConfiguration { callingInto: String, hold: Boolean, uuid: String = "unused" - ): Unit = { + )(implicit context: ActorContext): Unit = { def broadcastEvent(voiceUserState: VoiceUserState): Unit = { val routing = Routing.addMsgToClientRouting( @@ -324,10 +343,30 @@ object VoiceApp extends SystemConfiguration { hold, uuid ) + + val prevTransparentLOStatus = VoiceHdlrHelpers.transparentListenOnlyAllowed( + liveMeeting + ) + VoiceUsers.add(liveMeeting.voiceUsers, voiceUserState) UserVoiceDAO.update(voiceUserState) UserDAO.updateVoiceUserJoined(voiceUserState) + val newTransparentLOStatus = VoiceHdlrHelpers.transparentListenOnlyAllowed( + liveMeeting + ) + + if (prevTransparentLOStatus != newTransparentLOStatus) { + // If the transparent listen only mode was activated or deactivated + // we need to update the listen only mode for all users in the meeting + // that are not muted. + handleTransparentLOModeChange( + liveMeeting, + outGW, + newTransparentLOStatus + ) + } + broadcastEvent(voiceUserState) if (liveMeeting.props.meetingProp.isBreakout) { @@ -337,16 +376,19 @@ object VoiceApp extends SystemConfiguration { ) } - // if the meeting is muted tell freeswitch to mute the new person - if (!isListenOnly - && MeetingStatus2x.isMeetingMuted(liveMeeting.status)) { - val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg( - liveMeeting.props.meetingProp.intId, - voiceConf, - voiceUserId, - true - ) - outGW.send(event) + if (!isListenOnly) { + enforceMuteOnStartThreshold(liveMeeting, outGW) + + // if the meeting is muted tell freeswitch to mute the new person + if (MeetingStatus2x.isMeetingMuted(liveMeeting.status)) { + val event = MsgBuilder.buildMuteUserInVoiceConfSysMsg( + liveMeeting.props.meetingProp.intId, + voiceConf, + voiceUserId, + true + ) + outGW.send(event) + } } // Make sure lock settings are in effect. (ralam dec 6, 2019) @@ -395,6 +437,10 @@ object VoiceApp extends SystemConfiguration { } yield { VoiceUsers.removeWithIntId(liveMeeting.voiceUsers, user.meetingId, user.intId) broadcastEvent(user) + + if (!user.listenOnly) { + enforceMuteOnStartThreshold(liveMeeting, outGW) + } } if (liveMeeting.props.meetingProp.isBreakout) { @@ -405,6 +451,43 @@ object VoiceApp extends SystemConfiguration { } } + // Once #muteOnStartThreshold number of voice users is hit, we force + // meetingMute on MeetingStatus2x and broadcast MeetingMutedEvtMsg to clients. + // Otherwise, we broadcast MeetingMutedEvtMsg with the original muteOnStart + // muteOnStartThreshold = 0 means no threshold (disabled). + def enforceMuteOnStartThreshold( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter + ): Unit = { + val originalMuteOnStart = liveMeeting.props.voiceProp.muteOnStart + + if (muteOnStartThreshold == 0) { + return + } + + if (VoiceHdlrHelpers.muteOnStartThresholdReached(liveMeeting)) { + if (!MeetingStatus2x.isMeetingMuted(liveMeeting.status)) { + MeetingStatus2x.muteMeeting(liveMeeting.status) + val event = MsgBuilder.buildMeetingMutedEvtMsg( + liveMeeting.props.meetingProp.intId, + SystemUser.ID, + true, + SystemUser.ID + ) + outGW.send(event) + } + } else if (MeetingStatus2x.isMeetingMuted(liveMeeting.status) != originalMuteOnStart) { + MeetingStatus2x.setMeetingMuted(liveMeeting.status, originalMuteOnStart) + val event = MsgBuilder.buildMeetingMutedEvtMsg( + liveMeeting.props.meetingProp.intId, + SystemUser.ID, + originalMuteOnStart, + SystemUser.ID + ) + outGW.send(event) + } + } + /** Toggle audio for the given user in voice conference. * * We first stop the current audio being played, preventing the playback @@ -476,27 +559,62 @@ object VoiceApp extends SystemConfiguration { } } + def handleTransparentLOModeChange( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter, + allowed: Boolean, + )(implicit context: ActorContext): Unit = { + VoiceUsers.findAllMutedVoiceUsers(liveMeeting.voiceUsers) foreach { vu => + if (allowed) { + toggleListenOnlyMode( + liveMeeting, + outGW, + vu.intId, + vu.callerNum, + vu.muted + ) + } else { + toggleListenOnlyMode( + liveMeeting, + outGW, + vu.intId, + vu.callerNum, + false + ) + } + } + } + def toggleListenOnlyMode( liveMeeting: LiveMeeting, outGW: OutMsgRouter, userId: String, + callerNum: String, enabled: Boolean, delay: Int = 0 )(implicit context: ActorContext): Unit = { implicit def executionContext = context.system.dispatcher + val allowed = VoiceHdlrHelpers.transparentListenOnlyAllowed(liveMeeting) + // Guarantee there are no other tasks for this channel + removeToggleListenOnlyTask(userId) + + // If the meeting has not yet hit the minium amount of duplex channels + // for transparent listen only to be enabled, we don't need to do anything + if (!allowed && enabled) { + return + } + def broacastEvent(): Unit = { val event = MsgBuilder.buildToggleListenOnlyModeSysMsg( liveMeeting.props.meetingProp.intId, liveMeeting.props.voiceProp.voiceConf, userId, + callerNum, enabled ) outGW.send(event) } - // Guarantee there are no other tasks for this channel - removeToggleListenOnlyTask(userId) - if (enabled && delay > 0) { // If we are enabling listen only mode, we wait a bit before actually // dispatching the command - the idea is that recently muted users @@ -547,13 +665,15 @@ object VoiceApp extends SystemConfiguration { hold ) match { case Some(vu) => - // Mute vs hold state mismatch, enforce hold state again. - // Mute state is the predominant one here. - if (vu.muted != hold) { + // Mute vs hold state mismatch. Enforce it if the user is unmuted, + // but hold is active, to avoid the user being unable to talk when + // the channel is active again. + if (!vu.muted && vu.hold) { toggleListenOnlyMode( liveMeeting, outGW, intId, + vu.callerNum, vu.muted ) } @@ -570,4 +690,48 @@ object VoiceApp extends SystemConfiguration { case _ => } } + + def muteUserInVoiceConf( + liveMeeting: LiveMeeting, + outGW: OutMsgRouter, + userId: String, + muted: Boolean + )(implicit context: ActorContext): Unit = { + for { + u <- VoiceUsers.findWithIntId( + liveMeeting.voiceUsers, + userId + ) + } yield { + if (u.muted != muted) { + val muteEvent = MsgBuilder.buildMuteUserInVoiceConfSysMsg( + liveMeeting.props.meetingProp.intId, + liveMeeting.props.voiceProp.voiceConf, + u.voiceUserId, + muted + ) + + // If we're unmuting, trigger a channel unhold -> toggle listen only + // mode -> unmute + if (!muted) { + holdChannelInVoiceConf( + liveMeeting, + outGW, + u.uuid, + muted + ) + toggleListenOnlyMode( + liveMeeting, + outGW, + u.intId, + u.callerNum, + muted, + 0 + ) + } + + outGW.send(muteEvent) + } + } + } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp2x.scala index 301f0041cb..784fd909e0 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceApp2x.scala @@ -17,7 +17,6 @@ trait VoiceApp2x extends UserJoinedVoiceConfEvtMsgHdlr with UserTalkingInVoiceConfEvtMsgHdlr with RecordingStartedVoiceConfEvtMsgHdlr with VoiceConfRunningEvtMsgHdlr - with SyncGetVoiceUsersMsgHdlr with AudioFloorChangedVoiceConfEvtMsgHdlr with VoiceConfCallStateEvtMsgHdlr with UserStatusVoiceConfEvtMsgHdlr diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceHdlrHelpers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceHdlrHelpers.scala index cc9e59310f..f79fa1ac29 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceHdlrHelpers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/voice/VoiceHdlrHelpers.scala @@ -32,10 +32,6 @@ object VoiceHdlrHelpers extends SystemConfiguration { ): Boolean = { Users2x.findWithIntId(liveMeeting.users2x, userId) match { case Some(user) => { - val microphoneSharingLocked = LockSettingsUtil.isMicrophoneSharingLocked( - user, - liveMeeting - ) val isCallerBanned = VoiceUsers.isCallerBanned( callerIdNum, liveMeeting.voiceUsers @@ -43,11 +39,42 @@ object VoiceHdlrHelpers extends SystemConfiguration { (applyPermissionCheck && !isCallerBanned && - !microphoneSharingLocked && liveMeeting.props.meetingProp.intId == meetingId && liveMeeting.props.voiceProp.voiceConf == voiceConf) } case _ => false } } + + def isMicrophoneSharingLocked( + liveMeeting: LiveMeeting, + userId: String + ): Boolean = { + Users2x.findWithIntId(liveMeeting.users2x, userId) match { + case Some(user) => LockSettingsUtil.isMicrophoneSharingLocked( + user, + liveMeeting + ) && applyPermissionCheck + case _ => false + } + } + + def transparentListenOnlyAllowed(liveMeeting: LiveMeeting): Boolean = { + // Transparent listen only meeting-wide activation threshold. + // Threshold is the number of muted duplex audio channels in a meeting. + // 0 means no threshold, all users are subject to it + val mutedDuplexChannels = VoiceUsers.findAllMutedVoiceUsers(liveMeeting.voiceUsers).length + val threshold = transparentListenOnlyThreshold + + (threshold == 0) || (mutedDuplexChannels >= threshold) + } + + def muteOnStartThresholdReached(liveMeeting: LiveMeeting): Boolean = { + // Mute on start meeting-wide activation threshold. + // Threshold is the number of users in voice. + // muteOnStartThreshold = 0 means no threshold (disabled). + val usersInVoiceConf = VoiceUsers.usersInVoiceConf(liveMeeting.voiceUsers) + + muteOnStartThreshold > 0 && usersInVoiceConf >= muteOnStartThreshold + } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/webcam/SyncGetWebcamInfoRespMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/webcam/SyncGetWebcamInfoRespMsgHdlr.scala deleted file mode 100644 index 43c50cb961..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/webcam/SyncGetWebcamInfoRespMsgHdlr.scala +++ /dev/null @@ -1,48 +0,0 @@ -package org.bigbluebutton.core.apps.webcam - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.bus.MessageBus -import org.bigbluebutton.core.models.{ - Users2x, - VoiceUsers, - Webcams -} -import org.bigbluebutton.core.running.LiveMeeting - -trait SyncGetWebcamInfoRespMsgHdlr { - this: WebcamApp2x => - - def handleSyncGetWebcamInfoRespMsg(liveMeeting: LiveMeeting, bus: MessageBus): Unit = { - val routing = Routing.addMsgToClientRouting( - MessageTypes.BROADCAST_TO_MEETING, - liveMeeting.props.meetingProp.intId, - "nodeJSapp" - ) - val envelope = BbbCoreEnvelope(SyncGetWebcamInfoRespMsg.NAME, routing) - val header = BbbClientMsgHeader( - SyncGetWebcamInfoRespMsg.NAME, - liveMeeting.props.meetingProp.intId, - "nodeJSapp" - ) - - val webcamsList = Webcams.findAll(liveMeeting.webcams) flatMap { webcam => - val streamId = webcam.streamId - val userId = webcam.userId - val pin = Users2x.isPin(userId, liveMeeting.users2x) - for { - u <- Users2x.findWithIntId(liveMeeting.users2x, userId) - } yield { - VoiceUsers.findWIthIntId(liveMeeting.voiceUsers, userId) match { - case Some(vu) => WebcamStreamInfo(streamId, userId, u.name, pin, vu.floor, vu.lastFloorTime) - case _ => WebcamStreamInfo(streamId, userId, u.name, pin, false, "0") - } - } - } - - val body = SyncGetWebcamInfoRespMsgBody(webcamsList) - val event = SyncGetWebcamInfoRespMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - - bus.outGW.send(msgEvent) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/webcam/WebcamApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/webcam/WebcamApp2x.scala index 403dd977fd..27f2d3d1ca 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/webcam/WebcamApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/webcam/WebcamApp2x.scala @@ -11,7 +11,6 @@ class WebcamApp2x(implicit val context: ActorContext) with GetCamBroadcastPermissionReqMsgHdlr with GetCamSubscribePermissionReqMsgHdlr with GetWebcamsOnlyForModeratorReqMsgHdlr - with SyncGetWebcamInfoRespMsgHdlr with UpdateWebcamsOnlyForModeratorCmdMsgHdlr with UserBroadcastCamStartMsgHdlr with UserBroadcastCamStopMsgHdlr { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/BreakoutRoomDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/BreakoutRoomDAO.scala index d361e7ed42..cd329de18b 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/BreakoutRoomDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/BreakoutRoomDAO.scala @@ -3,12 +3,11 @@ package org.bigbluebutton.core.db import org.bigbluebutton.core.apps.BreakoutModel import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers import org.bigbluebutton.core.domain.BreakoutRoom2x +import org.bigbluebutton.core.models.{Roles, Users2x} import org.bigbluebutton.core.running.LiveMeeting import slick.jdbc.PostgresProfile.api._ -import scala.util.{Failure, Success} -import scala.concurrent.ExecutionContext.Implicits.global - +import scala.util.Random case class BreakoutRoomDbModel( breakoutRoomId: String, @@ -47,45 +46,60 @@ class BreakoutRoomDbTableDef(tag: Tag) extends Table[BreakoutRoomDbModel](tag, N } object BreakoutRoomDAO { - def insert(breakout: BreakoutModel, liveMeeting: LiveMeeting) = { - DatabaseConnection.db.run(DBIO.sequence( + DatabaseConnection.enqueue(DBIO.sequence( for { (_, room) <- breakout.rooms } yield { prepareInsertOrUpdate(room, breakout.durationInSeconds, breakout.sendInviteToModerators) } ).transactionally) - .onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on BreakoutRoom table!") - //Insert users - DatabaseConnection.db.run(DBIO.sequence( - for { - (_, room) <- breakout.rooms - userId <- room.assignedUsers - (redirectToHtml5JoinURL, redirectJoinURL) <- BreakoutHdlrHelpers.getRedirectUrls(liveMeeting, userId, room.externalId, room.sequence.toString()) - } yield { - BreakoutRoomUserDAO.prepareInsert(room.id, liveMeeting.props.meetingProp.intId, userId, redirectToHtml5JoinURL) - } - ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on breakoutRoom_user table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting breakoutRoom_user: $e") - } - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting BreakoutRoom: $e") + //Insert assigned users + DatabaseConnection.enqueue(DBIO.sequence( + for { + (_, room) <- breakout.rooms + userId <- room.assignedUsers + (redirectToHtml5JoinURL, redirectJoinURL) <- BreakoutHdlrHelpers.getRedirectUrls(liveMeeting, userId, room.externalId, room.sequence.toString()) + } yield { + BreakoutRoomUserDAO.prepareInsert(room.id, liveMeeting.props.meetingProp.intId, userId, redirectToHtml5JoinURL, wasAssignedByMod = true) + } + ).transactionally) + + //Assign left users to a random room in case it is freeJoin + val freeJoin = breakout.rooms.exists(r => r._2.freeJoin) + if(freeJoin) { + val assignedUsers = (for { + (_, room) <- breakout.rooms + userId <- room.assignedUsers + } yield { + userId + }).toVector + + val nonAssignedUsers = Users2x.findAll(liveMeeting.users2x) + .filterNot(user => assignedUsers.contains(user.intId)) + .filterNot(user => user.role == Roles.MODERATOR_ROLE) + .map(_.intId) + + val roomsSeq = breakout.rooms.values.toSeq + + DatabaseConnection.enqueue(DBIO.sequence( + for { + userId <- nonAssignedUsers + randomIndex = Random.nextInt(roomsSeq.length) + room <- Some(roomsSeq(randomIndex)) + (redirectToHtml5JoinURL, redirectJoinURL) <- BreakoutHdlrHelpers.getRedirectUrls(liveMeeting, userId, room.externalId, room.sequence.toString()) + } yield { + BreakoutRoomUserDAO.prepareInsert(room.id, liveMeeting.props.meetingProp.intId, userId, redirectToHtml5JoinURL, wasAssignedByMod = true) + } + ).transactionally) } } // def update(room: BreakoutRoom2x) = { -// DatabaseConnection.db.run( +// DatabaseConnection.enqueue( // prepareInsertOrUpdate(room) -// ).onComplete { -// case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on BreakoutRoom table!") -// case Failure(e) => DatabaseConnection.logger.error(s"Error updating BreakoutRoom: $e") -// } +// ) // } def prepareInsertOrUpdate(room: BreakoutRoom2x, durationInSeconds: Int, sendInvitationToModerators: Boolean) = { @@ -140,52 +154,40 @@ object BreakoutRoomDAO { // } def deletePermanently(meetingId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[BreakoutRoomDbTableDef] .filter(_.parentMeetingId === meetingId) .delete - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) delete of meeting ${meetingId} on BreakoutRooms table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error deleting BreakoutRoom of meeting ${meetingId}: $e") - } + ) } def updateRoomsStarted(meetingId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[BreakoutRoomDbTableDef] .filter(_.parentMeetingId === meetingId) // .filter(_.breakoutRoomId === breakoutRoomId) .map(u => u.startedAt) .update(Some(new java.sql.Timestamp(System.currentTimeMillis()))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated startedAt on BreakoutRoom table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating startedAt BreakoutRoom: $e") - } + ) } def updateRoomsEnded(meetingId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[BreakoutRoomDbTableDef] .filter(_.parentMeetingId === meetingId) .map(u => u.endedAt) .update(Some(new java.sql.Timestamp(System.currentTimeMillis()))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated endedAt on BreakoutRoom table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating endedAt BreakoutRoom: $e") - } + ) } def updateRoomsDuration(parentMeetingId: String, newDurationInSeconds: Int) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[BreakoutRoomDbTableDef] .filter(_.parentMeetingId === parentMeetingId) .filter(_.endedAt.isEmpty) .map(u => u.durationInSeconds) .update(newDurationInSeconds) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated endedAt on BreakoutRoom table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating endedAt BreakoutRoom: $e") - } + ) } // def update(meetingId: String, breakoutRoomModel: BreakoutRoomModel) = { @@ -193,7 +195,7 @@ object BreakoutRoomDAO { // TableQuery[BreakoutRoomDbTableDef] // .filter(_.meetingId === meetingId) // .map(t => (t.stopwatch, t.running, t.active, t.time, t.accumulated, t.startedAt, t.endedAt, t.songTrack)) -// .update((getStopwatch(breakoutRoomModel), getRunning(breakoutRoomModel), getIsACtive(breakoutRoomModel), getTime(breakoutRoomModel), getAccumulated(breakoutRoomModel), getStartedAt(breakoutRoomModel), getEndedAt(breakoutRoomModel), getTrack(breakoutRoomModel)) +// .update((isStopwatch(breakoutRoomModel), getRunning(breakoutRoomModel), getIsACtive(breakoutRoomModel), getTime(breakoutRoomModel), getAccumulated(breakoutRoomModel), getStartedAt(breakoutRoomModel), getEndedAt(breakoutRoomModel), getTrack(breakoutRoomModel)) // ) // ).onComplete { // case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on BreakoutRoom table!") diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/BreakoutRoomUserDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/BreakoutRoomUserDAO.scala index 23727e41da..62d28c0749 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/BreakoutRoomUserDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/BreakoutRoomUserDAO.scala @@ -2,20 +2,16 @@ package org.bigbluebutton.core.db import org.bigbluebutton.core.apps.breakout.BreakoutHdlrHelpers import org.bigbluebutton.core.domain.BreakoutRoom2x -import org.bigbluebutton.core.models.{RegisteredUsers, Roles} import org.bigbluebutton.core.running.LiveMeeting import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success} - case class BreakoutRoomUserDbModel( breakoutRoomId: String, meetingId: String, userId: String, joinURL: String, - joinedAt: Option[java.sql.Timestamp], assignedAt: Option[java.sql.Timestamp], + inviteDismissedAt: Option[java.sql.Timestamp], ) class BreakoutRoomUserDbTableDef(tag: Tag) extends Table[BreakoutRoomUserDbModel](tag, None, "breakoutRoom_user") { @@ -23,27 +19,30 @@ class BreakoutRoomUserDbTableDef(tag: Tag) extends Table[BreakoutRoomUserDbModel val meetingId = column[String]("meetingId", O.PrimaryKey) val userId = column[String]("userId", O.PrimaryKey) val joinURL = column[String]("joinURL") - val joinedAt = column[Option[java.sql.Timestamp]]("joinedAt") val assignedAt = column[Option[java.sql.Timestamp]]("assignedAt") - override def * = (breakoutRoomId, meetingId, userId, joinURL, joinedAt, assignedAt) <> (BreakoutRoomUserDbModel.tupled, BreakoutRoomUserDbModel.unapply) + val inviteDismissedAt = column[Option[java.sql.Timestamp]]("inviteDismissedAt") + override def * = (breakoutRoomId, meetingId, userId, joinURL, assignedAt, inviteDismissedAt) <> (BreakoutRoomUserDbModel.tupled, BreakoutRoomUserDbModel.unapply) } object BreakoutRoomUserDAO { - def prepareInsert(breakoutRoomId: String, meetingId: String, userId: String, joinURL: String) = { + def prepareInsert(breakoutRoomId: String, meetingId: String, userId: String, joinURL: String, wasAssignedByMod: Boolean) = { TableQuery[BreakoutRoomUserDbTableDef].insertOrUpdate( BreakoutRoomUserDbModel( breakoutRoomId = breakoutRoomId, meetingId = meetingId, userId = userId, joinURL = joinURL, - joinedAt = None, - assignedAt = Some(new java.sql.Timestamp(System.currentTimeMillis())), + assignedAt = wasAssignedByMod match { + case true => Some(new java.sql.Timestamp(System.currentTimeMillis())) + case false => None + }, + inviteDismissedAt = None, ) ) } - def prepareDelete(breakoutRoomId: String, meetingId: String, userId: String) = { + def prepareDelete(breakoutRoomId: String, meetingId: String, userId: String, exceptBreakoutRooomId: String) = { var query = TableQuery[BreakoutRoomUserDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) @@ -52,57 +51,60 @@ object BreakoutRoomUserDAO { if (breakoutRoomId.nonEmpty) { query = query.filter(_.breakoutRoomId === breakoutRoomId) } + + if (exceptBreakoutRooomId.nonEmpty) { + query = query.filter(_.breakoutRoomId =!= exceptBreakoutRooomId) + } + query.delete } - def updateRoomChanged(meetingId: String, userId: String, fromBreakoutRoomId: String, toBreakoutRoomId: String, joinUrl: String) = { - DatabaseConnection.db.run(DBIO.seq( - BreakoutRoomUserDAO.prepareDelete(fromBreakoutRoomId, meetingId, userId), - BreakoutRoomUserDAO.prepareInsert(toBreakoutRoomId, meetingId, userId, joinUrl) - ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) changed on breakoutRoom_user table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error changing breakoutRoom_user: $e") + def updateRoomChanged(meetingId: String, userId: String, fromBreakoutRoomId: String, + toBreakoutRoomId: String, joinUrl: String, removePreviousRoom: Boolean) = { + DatabaseConnection.enqueue( + if (removePreviousRoom) { + DBIO.seq( + BreakoutRoomUserDAO.prepareDelete(fromBreakoutRoomId, meetingId, userId, exceptBreakoutRooomId = toBreakoutRoomId), + BreakoutRoomUserDAO.prepareInsert(toBreakoutRoomId, meetingId, userId, joinUrl, wasAssignedByMod = true) + ) + } else { + DBIO.seq( + BreakoutRoomUserDAO.prepareInsert(toBreakoutRoomId, meetingId, userId, joinUrl, wasAssignedByMod = true) + ) } + ) } def updateUserJoined(meetingId: String, usersInRoom: Vector[String], breakoutRoom: BreakoutRoom2x) = { - DatabaseConnection.db.run( - TableQuery[BreakoutRoomUserDbTableDef] - .filter(_.meetingId === meetingId) - .filter(_.userId inSet usersInRoom) - .filter(_.breakoutRoomId === breakoutRoom.id) - .filter(_.joinedAt.isEmpty) - .map(u_bk => u_bk.joinedAt) - .update(Some(new java.sql.Timestamp(System.currentTimeMillis()))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated joinedAt=now() on breakoutRoom_user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating joinedAt=now() on breakoutRoom_user: $e") - } - } - - def updateUserEjected(meetingId: String, userId: String, breakoutRoomId: String) = { - DatabaseConnection.db.run(DBIO.seq( - BreakoutRoomUserDAO.prepareDelete(meetingId, userId, breakoutRoomId), - ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) deleted on breakoutRoom_user table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error deleting breakoutRoom_user: $e") - } + DatabaseConnection.enqueue( + sqlu"""UPDATE "breakoutRoom_user" SET + "joinedAt" = current_timestamp + WHERE "meetingId" = ${meetingId} + AND "userId" in (${usersInRoom.mkString(",")}) + AND "breakoutRoomId" = ${breakoutRoom.id} + AND "joinedAt" is null""" + ) } def insertBreakoutRoom(userId: String, room: BreakoutRoom2x, liveMeeting: LiveMeeting) = { for { (redirectToHtml5JoinURL, redirectJoinURL) <- BreakoutHdlrHelpers.getRedirectUrls(liveMeeting, userId, room.externalId, room.sequence.toString) } yield { - DatabaseConnection.db.run(BreakoutRoomUserDAO.prepareInsert(room.id, liveMeeting.props.meetingProp.intId, userId, redirectToHtml5JoinURL)) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on breakoutRoom_user table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting breakoutRoom_user: $e") - } + DatabaseConnection.enqueue(BreakoutRoomUserDAO.prepareInsert(room.id, liveMeeting.props.meetingProp.intId, userId, redirectToHtml5JoinURL, wasAssignedByMod = false)) } } + + def updateInviteDismissedAt(meetingId: String, userId: String) = { + DatabaseConnection.enqueue( + TableQuery[BreakoutRoomUserDbTableDef] + .filter(_.meetingId === meetingId) + .filter(_.userId === userId) + .map(u => (u.inviteDismissedAt)) + .update(Some(new java.sql.Timestamp(System.currentTimeMillis()))) + ) + } + // def updateUserJoined(meetingId: String, userId: String, breakoutRoomId: String) = { // DatabaseConnection.db.run( // TableQuery[BreakoutRoomUserDbTableDef] diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionDAO.scala index e353fb4ef5..7d680d0d3e 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionDAO.scala @@ -1,8 +1,6 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } case class CaptionDbModel( captionId: String, @@ -32,23 +30,21 @@ object CaptionTypes { object CaptionDAO { - def insertOrUpdateAudioCaption(captionId: String, meetingId: String, userId: String, transcript: String, locale: String) = { - DatabaseConnection.db.run( + def insertOrUpdateCaption(captionId: String, meetingId: String, userId: String, transcript: String, + locale: String, captionType: String = CaptionTypes.AUDIO_TRANSCRIPTION) = { + DatabaseConnection.enqueue( TableQuery[CaptionTableDef].insertOrUpdate( CaptionDbModel( captionId = captionId, meetingId = meetingId, - captionType = CaptionTypes.AUDIO_TRANSCRIPTION, + captionType = captionType, userId = userId, locale = locale, captionText = transcript, createdAt = new java.sql.Timestamp(System.currentTimeMillis()) ) ) - ).onComplete { - case Success(_) => DatabaseConnection.logger.debug(s"Upserted caption with ID $captionId on Caption table") - case Failure(e) => DatabaseConnection.logger.debug(s"Error upserting caption on Caption: $e") - } + ) } def insertOrUpdatePadCaption(meetingId: String, locale: String, userId: String, text: String) = { @@ -93,12 +89,6 @@ object CaptionDAO { )""" } - DatabaseConnection.db.run(DBIO.sequence(actions).transactionally).onComplete { - case Success(rowsAffected) => - val total = rowsAffected.sum - DatabaseConnection.logger.debug(s"$total row(s) affected in caption table!") - case Failure(e) => - DatabaseConnection.logger.error(s"Error executing action: ", e) - } + DatabaseConnection.enqueue(DBIO.sequence(actions).transactionally) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionLangDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionLocaleDAO.scala similarity index 56% rename from akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionLangDAO.scala rename to akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionLocaleDAO.scala index 9b34bc1c81..e1478b5612 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionLangDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/CaptionLocaleDAO.scala @@ -1,14 +1,12 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } case class CaptionLocaleDbModel( meetingId: String, locale: String, captionType: String, - ownerUserId: String, + createdBy: String, updatedAt: java.sql.Timestamp ) @@ -16,26 +14,23 @@ class CaptionLocaleTableDef(tag: Tag) extends Table[CaptionLocaleDbModel](tag, N val meetingId = column[String]("meetingId", O.PrimaryKey) val locale = column[String]("locale", O.PrimaryKey) val captionType = column[String]("captionType", O.PrimaryKey) - val ownerUserId = column[String]("ownerUserId") + val createdBy = column[String]("createdBy") val updatedAt = column[java.sql.Timestamp]("updatedAt") - def * = (meetingId, locale, captionType, ownerUserId, updatedAt) <> (CaptionLocaleDbModel.tupled, CaptionLocaleDbModel.unapply) + def * = (meetingId, locale, captionType, createdBy, updatedAt) <> (CaptionLocaleDbModel.tupled, CaptionLocaleDbModel.unapply) } object CaptionLocaleDAO { - def insertOrUpdateCaptionLocale(meetingId: String, locale: String, captionType: String, ownerUserId: String) = { - DatabaseConnection.db.run( + def insertOrUpdateCaptionLocale(meetingId: String, locale: String, captionType: String, userId: String) = { + DatabaseConnection.enqueue( TableQuery[CaptionLocaleTableDef].insertOrUpdate( CaptionLocaleDbModel( meetingId = meetingId, locale = locale, captionType = captionType, - ownerUserId = ownerUserId, + createdBy = userId, updatedAt = new java.sql.Timestamp(System.currentTimeMillis()) ) ) - ).onComplete { - case Success(_) => DatabaseConnection.logger.debug(s"Upserted caption with ID $meetingId-$locale on CaptionLocale table") - case Failure(e) => DatabaseConnection.logger.debug(s"Error upserting caption on CaptionLocale: $e") - } + ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatDAO.scala index 8d4fb9d2ca..f63d20baf7 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatDAO.scala @@ -3,9 +3,6 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ import org.bigbluebutton.core.models.GroupChat -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class ChatDbModel( chatId: String, meetingId: String, @@ -24,7 +21,7 @@ class ChatDbTableDef(tag: Tag) extends Table[ChatDbModel](tag, None, "chat") { object ChatDAO { def insert(meetingId: String, groupChat: GroupChat) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ChatDbTableDef].insertOrUpdate( ChatDbModel( chatId = groupChat.id, @@ -33,18 +30,12 @@ object ChatDAO { createdBy = groupChat.createdBy.id, ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on Chat table!") + ) - for { - user <- groupChat.users - } yield { - ChatUserDAO.insert(meetingId, groupChat.id, user, visible = groupChat.createdBy.id == user.id) - } - - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting Chat: $e") - } + for { + user <- groupChat.users + } yield { + ChatUserDAO.insert(meetingId, groupChat.id, user, visible = groupChat.createdBy.id == user.id) + } } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatMessageDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatMessageDAO.scala index 160f5e4a86..bedbaa3c71 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatMessageDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatMessageDAO.scala @@ -3,9 +3,6 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ import org.bigbluebutton.core.models.{GroupChatFactory, GroupChatMessage} -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success} - case class ChatMessageDbModel( messageId: String, chatId: String, @@ -41,8 +38,8 @@ class ChatMessageDbTableDef(tag: Tag) extends Table[ChatMessageDbModel](tag, Non } object ChatMessageDAO { - def insert(meetingId: String, chatId: String, groupChatMessage: GroupChatMessage) = { - DatabaseConnection.db.run( + def insert(meetingId: String, chatId: String, groupChatMessage: GroupChatMessage, messageType: String) = { + DatabaseConnection.enqueue( TableQuery[ChatMessageDbTableDef].insertOrUpdate( ChatMessageDbModel( messageId = groupChatMessage.id, @@ -52,26 +49,41 @@ object ChatMessageDAO { createdAt = new java.sql.Timestamp(System.currentTimeMillis()), chatEmphasizedText = groupChatMessage.chatEmphasizedText, message = groupChatMessage.message, - messageType = "default", - messageMetadata = None, + messageType = messageType, + messageMetadata = Some(JsonUtils.mapToJson(groupChatMessage.metadata).compactPrint), senderId = Some(groupChatMessage.sender.id), senderName = groupChatMessage.sender.name, senderRole = Some(groupChatMessage.sender.role), ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on ChatMessage table!") + ) - //Set chat visible for all participant users - ChatUserDAO.updateChatVisible(meetingId, chatId) - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting ChatMessage: $e") - } + //Set chat visible for all participant users + ChatUserDAO.updateChatVisible(meetingId, chatId, visible = true) } +// def insert(meetingId: String, chatId: String, groupChatMessage: GroupChatMessage): Unit = { +// val chatMessage = ChatMessageDbModel( +// messageId = groupChatMessage.id, +// chatId = chatId, +// meetingId = meetingId, +// correlationId = groupChatMessage.correlationId, +// createdAt = new java.sql.Timestamp(System.currentTimeMillis()), +// chatEmphasizedText = groupChatMessage.chatEmphasizedText, +// message = groupChatMessage.message, +// messageType = "default", +// messageMetadata = None, +// senderId = Some(groupChatMessage.sender.id), +// senderName = groupChatMessage.sender.name, +// senderRole = Some(groupChatMessage.sender.role), +// ) +// +// val insertAction = TableQuery[ChatMessageDbTableDef].insertOrUpdate(chatMessage) +// DatabaseConnection.enqueue(insertAction) +// } + def insertSystemMsg(meetingId: String, chatId: String, message: String, messageType: String, messageMetadata: Map[String,Any], senderName: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ChatMessageDbTableDef].insertOrUpdate( ChatMessageDbModel( messageId = GroupChatFactory.genId(), @@ -88,27 +100,19 @@ object ChatMessageDAO { senderRole = None ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on ChatMessage(system) table!") + ) - //Set chat visible for all participant users - ChatUserDAO.updateChatVisible(meetingId, chatId) - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting ChatMessage(system): $e") - } + //Set chat visible for all participant users + ChatUserDAO.updateChatVisible(meetingId, chatId, visible = true) } def deleteAllFromChat(meetingId: String, chatId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ChatMessageDbTableDef] .filter(_.meetingId === meetingId) .filter(_.chatId === chatId) .delete - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) deleted from ChatMessage meetingId=${meetingId} chatId=${chatId}") - case Failure(e) => DatabaseConnection.logger.error(s"Error deleting from ChatMessage meetingId=${meetingId} chatId=${chatId}: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatUserDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatUserDAO.scala index b6163490c7..e5cb291a00 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatUserDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ChatUserDAO.scala @@ -2,10 +2,6 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ import org.bigbluebutton.common2.msgs.GroupChatUser -import org.bigbluebutton.core.models.VoiceUserState - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } case class ChatUserDbModel( chatId: String, @@ -42,7 +38,7 @@ object ChatUserDAO { } def insertUser(meetingId: String, chatId: String, userId: String, visible: Boolean) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ChatUserDbTableDef].insertOrUpdate( ChatUserDbModel( userId = userId, @@ -54,41 +50,44 @@ object ChatUserDAO { visible = visible ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on ChatUser table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting ChatUser: $e") - } + ) } def updateUserTyping(meetingId: String, chatId: String, userId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ChatUserDbTableDef] .filter(_.meetingId === meetingId) .filter(_.chatId === (if (chatId == "public") "MAIN-PUBLIC-GROUP-CHAT" else chatId)) .filter(_.userId === userId) .map(u => (u.lastTypingAt)) .update(Some(new java.sql.Timestamp(System.currentTimeMillis()))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated lastTypingAt on chat_user table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating lastTypingAt on chat_user table: $e") - } + ) } - def updateChatVisible(meetingId: String, chatId: String, userId: String = ""): Unit = { + def updateChatVisible(meetingId: String, chatId: String, userId: String = "", visible: Boolean): Unit = { if (chatId != "MAIN-PUBLIC-GROUP-CHAT" && chatId != "public") { //Public chat is always visible val baseQuery = TableQuery[ChatUserDbTableDef] .filter(_.meetingId === meetingId) .filter(_.chatId === chatId) - .filter(_.visible === false) + .filter(_.visible === !visible) val updateQuery = if (userId.nonEmpty) { - baseQuery.filter(_.userId === userId).map(_.visible).update(true) + baseQuery.filter(_.userId === userId).map(_.visible).update(visible) } else { - baseQuery.map(_.visible).update(true) - } - DatabaseConnection.db.run(updateQuery).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated visible on chat_user table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating visible on chat_user table: $e") + baseQuery.map(_.visible).update(visible) } + DatabaseConnection.enqueue(updateQuery) } } + + def updateChatLastSeen(meetingId: String, chatId: String, userId: String, lastSeenAt: java.sql.Timestamp) = { + DatabaseConnection.enqueue( + TableQuery[ChatUserDbTableDef] + .filter(_.meetingId === meetingId) + .filter(_.chatId === (if (chatId == "public") "MAIN-PUBLIC-GROUP-CHAT" else chatId)) + .filter(_.userId === userId) + .map(u => (u.lastSeenAt)) + .update(Some(lastSeenAt)) + ) + } + } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/DatabaseConnection.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/DatabaseConnection.scala index 967374c3bf..e2b89ea1a7 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/DatabaseConnection.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/DatabaseConnection.scala @@ -3,13 +3,26 @@ package org.bigbluebutton.core.db import org.slf4j.LoggerFactory import slick.jdbc.PostgresProfile.api._ +import scala.concurrent.duration._ +import java.util.concurrent.ConcurrentLinkedQueue import scala.concurrent.ExecutionContext.Implicits.global +import java.util.concurrent.atomic.AtomicBoolean +import scala.util.control.Breaks._ object DatabaseConnection { val db = Database.forConfig("postgres") - // implicit val session: Session = db.createSession() val logger = LoggerFactory.getLogger(this.getClass) + val queue = new ConcurrentLinkedQueue[DBIO[_]]() + val isProcessing = new AtomicBoolean(false) + val batchSizeLimit = 500 + + // Initialize the scheduler for batch processing + val system = org.apache.pekko.actor.ActorSystem("DBActionBatchSystem") + system.scheduler.scheduleWithFixedDelay(50.millis, 50.millis)(new Runnable { + def run(): Unit = tryProcessBatch() + }) + def initialize(): Unit = { db.run(sql"SELECT current_timestamp".as[java.sql.Timestamp]).map { timestamp => logger.debug(s"Database initialized, current timestamp is: $timestamp") @@ -18,4 +31,48 @@ object DatabaseConnection { logger.error(s"Failed to initialize database: ${ex.getMessage}") } } + + def enqueue(action: DBIO[_]): Unit = { + queue.add(action) + tryProcessBatch() + } + + private def tryProcessBatch(): Unit = { + if (isProcessing.compareAndSet(false, true)) { + processBatch() + } + } + + private def processBatch(): Unit = { + val batch = collection.mutable.ListBuffer[DBIO[_]]() + breakable { + var action = queue.poll() + while (action != null) { + batch += action + if (batch.size >= batchSizeLimit) { + break() + } + action = queue.poll() + } + } + + if (batch.nonEmpty) { + val startTime = System.nanoTime() + val combinedAction = DBIO.sequence(batch.toList) + db.run(combinedAction).onComplete { + case scala.util.Success(_) => + val endTime = System.nanoTime() + val duration = (endTime - startTime) / 1e6 // convert to milliseconds + logger.debug(s"${batch.size} actions executed in the database in $duration ms.") + isProcessing.set(false) + if (!queue.isEmpty) tryProcessBatch() + case scala.util.Failure(e) => + logger.error(s"Error executing batch actions: $e") + isProcessing.set(false) + if (!queue.isEmpty) tryProcessBatch() + } + } else { + isProcessing.set(false) + } + } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ExternalVideoDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ExternalVideoDAO.scala index d770fc14ef..9ccfcd122c 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ExternalVideoDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ExternalVideoDAO.scala @@ -4,9 +4,6 @@ import org.bigbluebutton.core.util.RandomStringGenerator import slick.jdbc.PostgresProfile.api._ import slick.lifted.ProvenShape -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class ExternalVideoDbModel( externalVideoId: String, meetingId: String, @@ -34,7 +31,7 @@ class ExternalVideoDbTableDef(tag: Tag) extends Table[ExternalVideoDbModel](tag, object ExternalVideoDAO { def insert(meetingId: String, externalVideoUrl: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ExternalVideoDbTableDef].forceInsert( ExternalVideoDbModel( externalVideoId = System.currentTimeMillis() + "-" + RandomStringGenerator.randomAlphanumericString(8), @@ -48,14 +45,11 @@ object ExternalVideoDAO { playerPlaying = true ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in ExternalVideo table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting ExternalVideo: $e") - } + ) } def update(meetingId: String, status: String, rate: Double, time: Double, state: Int) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ExternalVideoDbTableDef] .filter(_.meetingId === meetingId) .filter(_.stoppedSharingAt.isEmpty) @@ -73,23 +67,17 @@ object ExternalVideoDAO { }, new java.sql.Timestamp(System.currentTimeMillis()) )) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on ExternalVideo table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating ExternalVideo: $e") - } + ) } def updateStoppedSharing(meetingId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ExternalVideoDbTableDef] .filter(_.meetingId === meetingId) .filter(_.stoppedSharingAt.isEmpty) .map(ev => (ev.stoppedSharingAt, ev.playerPlaying)) .update(Some(new java.sql.Timestamp(System.currentTimeMillis())), false) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated stoppedSharingAt on ExternalVideo table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating stoppedSharingAt on ExternalVideo: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/LayoutDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/LayoutDAO.scala index 7513fb5742..e4b2395dbb 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/LayoutDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/LayoutDAO.scala @@ -4,9 +4,6 @@ import org.bigbluebutton.core.models.Layouts import org.bigbluebutton.core.models.Layouts.{getCameraDockIsResizing, getCameraPosition, getCurrentLayout, getFocusedCamera, getPresentationIsOpen, getPresentationVideoRate, getPushLayout, setCurrentLayout} import slick.jdbc.PostgresProfile.api._ -import scala.util.{Failure, Success} -import scala.concurrent.ExecutionContext.Implicits.global - case class LayoutDbModel( meetingId: String, currentLayoutType: String, @@ -41,7 +38,7 @@ object LayoutDAO { } def insertOrUpdate(meetingId: String, layout: Layouts) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[LayoutDbTableDef].insertOrUpdate( LayoutDbModel( meetingId = meetingId, @@ -55,9 +52,6 @@ object LayoutDAO { updatedAt = new java.sql.Timestamp(System.currentTimeMillis()) ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted/updated on Layout table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting/updating Layout: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingBreakoutDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingBreakoutDAO.scala index 85bb3df271..54fb7a6802 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingBreakoutDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingBreakoutDAO.scala @@ -4,9 +4,6 @@ import org.bigbluebutton.common2.domain.{ BreakoutProps } import slick.lifted.ProvenShape import PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success, Try } - case class MeetingBreakoutDbModel( meetingId: String, parentId: String, @@ -41,7 +38,7 @@ class MeetingBreakoutDbTableDef(tag: Tag) extends Table[MeetingBreakoutDbModel]( object MeetingBreakoutDAO { def insert(meetingId: String, breakoutProps: BreakoutProps) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingBreakoutDbTableDef].forceInsert( MeetingBreakoutDbModel( meetingId = meetingId, @@ -58,11 +55,6 @@ object MeetingBreakoutDAO { captureSlidesFilename = breakoutProps.captureSlidesFilename ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingBreakout table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingBreakout: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingClientSettingsDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingClientSettingsDAO.scala index f48fd574f8..06ce7e1f69 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingClientSettingsDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingClientSettingsDAO.scala @@ -3,8 +3,6 @@ package org.bigbluebutton.core.db import PostgresProfile.api._ import slick.lifted.ProvenShape import spray.json.JsValue -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success} case class MeetingClientSettingsDbModel( meetingId: String, @@ -20,19 +18,14 @@ class MeetingClientSettingsDbTableDef(tag: Tag) extends Table[MeetingClientSetti object MeetingClientSettingsDAO { def insert(meetingId: String, clientSettingsJson: JsValue) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingClientSettingsDbTableDef].forceInsert( MeetingClientSettingsDbModel( meetingId = meetingId, clientSettingsJson = clientSettingsJson ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingClientSettings table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingClientSettings: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingDAO.scala index 6fb5f5468b..7b20dc3e14 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingDAO.scala @@ -4,13 +4,11 @@ import org.bigbluebutton.common2.domain.DefaultProps import PostgresProfile.api._ import org.bigbluebutton.core.apps.groupchats.GroupChatApp -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class MeetingSystemColumnsDbModel( loginUrl: Option[String], logoutUrl: Option[String], customLogoUrl: Option[String], + customDarkLogoUrl: Option[String], bannerText: Option[String], bannerColor: Option[String], ) @@ -73,9 +71,10 @@ class MeetingDbTableDef(tag: Tag) extends Table[MeetingDbModel](tag, None, "meet val loginUrl = column[Option[String]]("loginUrl") val logoutUrl = column[Option[String]]("logoutUrl") val customLogoUrl = column[Option[String]]("customLogoUrl") + val customDarkLogoUrl = column[Option[String]]("customDarkLogoUrl") val bannerText = column[Option[String]]("bannerText") val bannerColor = column[Option[String]]("bannerColor") - val systemColumns = (loginUrl, logoutUrl, customLogoUrl, bannerText, bannerColor) <> (MeetingSystemColumnsDbModel.tupled, MeetingSystemColumnsDbModel.unapply) + val systemColumns = (loginUrl, logoutUrl, customLogoUrl, customDarkLogoUrl, bannerText, bannerColor) <> (MeetingSystemColumnsDbModel.tupled, MeetingSystemColumnsDbModel.unapply) val createdTime = column[Long]("createdTime") val durationInSeconds = column[Int]("durationInSeconds") val endWhenNoModerator = column[Boolean]("endWhenNoModerator") @@ -87,7 +86,7 @@ class MeetingDbTableDef(tag: Tag) extends Table[MeetingDbModel](tag, None, "meet object MeetingDAO { def insert(meetingProps: DefaultProps, clientSettings: Map[String, Object]) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingDbTableDef].forceInsert( MeetingDbModel( meetingId = meetingProps.meetingProp.intId, @@ -114,6 +113,10 @@ object MeetingDAO { case "" => None case logoUrl => Some(logoUrl) }, + customDarkLogoUrl = meetingProps.systemProps.customDarkLogoURL match { + case "" => None + case darkLogoUrl => Some(darkLogoUrl) + }, bannerText = meetingProps.systemProps.bannerText match { case "" => None case bannerText => Some(bannerText) @@ -132,24 +135,19 @@ object MeetingDAO { endedBy = None ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in Meeting table!") - ChatDAO.insert(meetingProps.meetingProp.intId, GroupChatApp.createDefaultPublicGroupChat()) - MeetingUsersPoliciesDAO.insert(meetingProps.meetingProp.intId, meetingProps.usersProp) - MeetingLockSettingsDAO.insert(meetingProps.meetingProp.intId, meetingProps.lockSettingsProps) - MeetingMetadataDAO.insert(meetingProps.meetingProp.intId, meetingProps.metadataProp) - MeetingRecordingPoliciesDAO.insert(meetingProps.meetingProp.intId, meetingProps.recordProp) - MeetingVoiceDAO.insert(meetingProps.meetingProp.intId, meetingProps.voiceProp) - MeetingWelcomeDAO.insert(meetingProps.meetingProp.intId, meetingProps.welcomeProp) - MeetingGroupDAO.insert(meetingProps.meetingProp.intId, meetingProps.groups) - MeetingBreakoutDAO.insert(meetingProps.meetingProp.intId, meetingProps.breakoutProps) - TimerDAO.insert(meetingProps.meetingProp.intId, clientSettings) - LayoutDAO.insert(meetingProps.meetingProp.intId, meetingProps.usersProp.meetingLayout) - MeetingClientSettingsDAO.insert(meetingProps.meetingProp.intId, JsonUtils.mapToJson(clientSettings)) - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting Meeting: $e") - } + ) + + ChatDAO.insert(meetingProps.meetingProp.intId, GroupChatApp.createDefaultPublicGroupChat()) + MeetingUsersPoliciesDAO.insert(meetingProps.meetingProp.intId, meetingProps.usersProp) + MeetingLockSettingsDAO.insert(meetingProps.meetingProp.intId, meetingProps.lockSettingsProps) + MeetingMetadataDAO.insert(meetingProps.meetingProp.intId, meetingProps.metadataProp) + MeetingRecordingPoliciesDAO.insert(meetingProps.meetingProp.intId, meetingProps.recordProp) + MeetingVoiceDAO.insert(meetingProps.meetingProp.intId, meetingProps.voiceProp) + MeetingWelcomeDAO.insert(meetingProps.meetingProp.intId, meetingProps.welcomeProp) + MeetingGroupDAO.insert(meetingProps.meetingProp.intId, meetingProps.groups) + MeetingBreakoutDAO.insert(meetingProps.meetingProp.intId, meetingProps.breakoutProps) + LayoutDAO.insert(meetingProps.meetingProp.intId, meetingProps.usersProp.meetingLayout) + MeetingClientSettingsDAO.insert(meetingProps.meetingProp.intId, JsonUtils.mapToJson(clientSettings)) } def updateMeetingDurationByParentMeeting(parentMeetingId: String, newDurationInSeconds: Int) = { @@ -158,33 +156,38 @@ object MeetingDAO { .filter(_.endedAt.isEmpty) .map(_.externalId) - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingDbTableDef] .filter(_.extId in subqueryBreakoutRooms) .map(u => u.durationInSeconds) .update(newDurationInSeconds) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated durationInSeconds on Meeting table") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating durationInSeconds on Meeting: $e") - } + ) } def delete(meetingId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingDbTableDef] .filter(_.meetingId === meetingId) .delete - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"Meeting ${meetingId} deleted") - case Failure(e) => DatabaseConnection.logger.debug(s"Error deleting meeting ${meetingId}: $e") - } + ) } + def deleteOldMeetings() = { + val oneHourAgo = java.sql.Timestamp.from(java.time.Instant.now().minusSeconds(3600)) + + DatabaseConnection.enqueue( + TableQuery[MeetingDbTableDef] + .filter(_.endedAt < oneHourAgo) + .delete + ) + } + + def setMeetingEnded(meetingId: String, endedReasonCode: String, endedBy: String) = { UserDAO.softDeleteAllFromMeeting(meetingId) - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingDbTableDef] .filter(_.meetingId === meetingId) .map(a => (a.endedAt, a.endedReasonCode, a.endedBy)) @@ -198,14 +201,11 @@ object MeetingDAO { } ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated endedAt=now() on Meeting table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating endedAt=now() Meeting: $e") - } + ) } def setAllMeetingsEnded(endedReasonCode: String, endedBy: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingDbTableDef] .filter(_.endedAt.isEmpty) .map(a => (a.endedAt, a.endedReasonCode, a.endedBy)) @@ -219,10 +219,7 @@ object MeetingDAO { } ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated all-meetings endedAt=now() on Meeting table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating all-meetings endedAt=now() on Meeting table: $e") - } + ) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingGroupDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingGroupDAO.scala index fa0dc46fe8..67004a74e9 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingGroupDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingGroupDAO.scala @@ -4,9 +4,6 @@ import org.bigbluebutton.common2.domain.{ GroupProps } import PostgresProfile.api._ import slick.lifted.{ ProvenShape } -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success, Try } - case class MeetingGroupDbModel( meetingId: String, groupId: String, @@ -27,7 +24,7 @@ class MeetingGroupDbTableDef(tag: Tag) extends Table[MeetingGroupDbModel](tag, N object MeetingGroupDAO { def insert(meetingId: String, groups: Vector[GroupProps]) = { - DatabaseConnection.db.run(DBIO.sequence( + DatabaseConnection.enqueue(DBIO.sequence( for { group <- groups } yield { @@ -41,9 +38,5 @@ object MeetingGroupDAO { ) } ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on MeetingGroup table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting MeetingGroup: $e") - } } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingLockSettingsDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingLockSettingsDAO.scala index b4932fde5a..5e7b45b0e0 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingLockSettingsDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingLockSettingsDAO.scala @@ -5,9 +5,6 @@ import org.bigbluebutton.core2.Permissions import slick.jdbc.PostgresProfile.api._ import slick.lifted.ProvenShape -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class MeetingLockSettingsDbModel( meetingId: String, disableCam: Boolean, @@ -42,7 +39,7 @@ class MeetingLockSettingsDbTableDef(tag: Tag) extends Table[MeetingLockSettingsD object MeetingLockSettingsDAO { def insert(meetingId: String, lockSettingsProps: LockSettingsProps) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingLockSettingsDbTableDef].forceInsert( MeetingLockSettingsDbModel( meetingId = meetingId, @@ -58,16 +55,11 @@ object MeetingLockSettingsDAO { hideViewersAnnotation = lockSettingsProps.hideViewersAnnotation, ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingLockSettings table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingLockSettings: $e") - } + ) } def update(meetingId: String, permissions: Permissions) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingLockSettingsDbTableDef].insertOrUpdate( MeetingLockSettingsDbModel( meetingId = meetingId, @@ -83,12 +75,7 @@ object MeetingLockSettingsDAO { hideViewersAnnotation = permissions.hideViewersAnnotation, ), ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated in MeetingLockSettings table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error updating MeetingLockSettings: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingMetadataDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingMetadataDAO.scala index 01fecb5184..652003d7a0 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingMetadataDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingMetadataDAO.scala @@ -4,9 +4,6 @@ import org.bigbluebutton.common2.domain.{ MetadataProp } import slick.jdbc.PostgresProfile.api._ import slick.lifted.{ ProvenShape } -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class MeetingMetadataDbModel( meetingId: String, name: String, @@ -27,7 +24,7 @@ class MeetingMetadataDbTableDef(tag: Tag) extends Table[MeetingMetadataDbModel]( object MeetingMetadataDAO { def insert(meetingId: String, metadataProp: MetadataProp) = { - DatabaseConnection.db.run(DBIO.sequence( + DatabaseConnection.enqueue(DBIO.sequence( for { metadata <- metadataProp.metadata } yield { @@ -40,9 +37,5 @@ object MeetingMetadataDAO { ) } ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on MeetingMetadata table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting MeetingMetadata: $e") - } } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingRecordingDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingRecordingDAO.scala index 864cc2efc6..ccbb9325ff 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingRecordingDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingRecordingDAO.scala @@ -3,9 +3,6 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ import slick.lifted.{ ProvenShape } -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class MeetingRecordingDbModel( meetingId: String, startedAt: java.sql.Timestamp, @@ -32,7 +29,7 @@ object MeetingRecordingDAO { //Stop any previous recoding for this meeting before starting a new one updateStopped(meetingId, startedBy) - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingRecordingDbTableDef].forceInsert( MeetingRecordingDbModel( meetingId = meetingId, @@ -42,25 +39,17 @@ object MeetingRecordingDAO { stoppedBy = None, ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingRecording table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingRecording: $e") - } + ) } def updateStopped(meetingId: String, stoppedBy: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingRecordingDbTableDef] .filter(_.meetingId === meetingId) .filter(_.stoppedAt.isEmpty) .map(r => (r.stoppedAt, r.stoppedBy)) .update(Some(new java.sql.Timestamp(System.currentTimeMillis())), Some(stoppedBy)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated stoppedAt on MeetingRecording table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating stoppedAt on MeetingRecording: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingRecordingPoliciesDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingRecordingPoliciesDAO.scala index 3a55ca458d..7517c93ff8 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingRecordingPoliciesDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingRecordingPoliciesDAO.scala @@ -4,9 +4,6 @@ import org.bigbluebutton.common2.domain.{ RecordProp } import slick.jdbc.PostgresProfile.api._ import slick.lifted.{ ProvenShape } -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class MeetingRecordingPoliciesDbModel( meetingId: String, record: Boolean, @@ -28,7 +25,7 @@ class MeetingRecordingPoliciesDbTableDef(tag: Tag) extends Table[MeetingRecordin object MeetingRecordingPoliciesDAO { def insert(meetingId: String, recordProp: RecordProp) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingRecordingPoliciesDbTableDef].forceInsert( MeetingRecordingPoliciesDbModel( meetingId = meetingId, @@ -38,12 +35,7 @@ object MeetingRecordingPoliciesDAO { keepEvents = recordProp.keepEvents ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingRecordingPolicies table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingRecordingPolicies: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala index cbfab07a53..a4aa31d8a5 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingUsersPoliciesDAO.scala @@ -5,9 +5,6 @@ import org.bigbluebutton.core.models.GuestPolicy import slick.jdbc.PostgresProfile.api._ import slick.lifted.ProvenShape -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success} - case class MeetingUsersPoliciesDbModel( meetingId: String, maxUsers: Int, @@ -44,7 +41,7 @@ class MeetingUsersPoliciesDbTableDef(tag: Tag) extends Table[MeetingUsersPolicie object MeetingUsersPoliciesDAO { def insert(meetingId:String, usersProp: UsersProp) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingUsersPoliciesDbTableDef].forceInsert( MeetingUsersPoliciesDbModel( meetingId = meetingId, @@ -61,28 +58,20 @@ object MeetingUsersPoliciesDAO { allowPromoteGuestToModerator = usersProp.allowPromoteGuestToModerator, ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingUsersPolicies table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingUsersPolicies: $e") - } + ) } def update(meetingId: String, policy: GuestPolicy) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingUsersPoliciesDbTableDef] .filter(_.meetingId === meetingId) .map(u => u.guestPolicy) .update(policy.policy) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated guestPolicy on meeting_usersPolicies table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating guestPolicy on meeting_usersPolicies: $e") - } + ) } def updateGuestLobbyMessage(meetingId: String, guestLobbyMessage: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingUsersPoliciesDbTableDef] .filter(_.meetingId === meetingId) .map(u => u.guestLobbyMessage) @@ -92,22 +81,16 @@ object MeetingUsersPoliciesDAO { case m => Some(m) } ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated guestLobbyMessage on meeting_usersPolicies table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating guestLobbyMessage on meeting_usersPolicies: $e") - } + ) } def updateWebcamsOnlyForModerator(meetingId: String, webcamsOnlyForModerator: Boolean) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingUsersPoliciesDbTableDef] .filter(_.meetingId === meetingId) .map(u => u.webcamsOnlyForModerator) .update(webcamsOnlyForModerator) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated webcamsOnlyForModerator on meeting_usersPolicies table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating webcamsOnlyForModerator on meeting_usersPolicies: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingVoiceDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingVoiceDAO.scala index 8299f55a38..6c714ac9a0 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingVoiceDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingVoiceDAO.scala @@ -4,9 +4,6 @@ import org.bigbluebutton.common2.domain.{ VoiceProp } import slick.jdbc.PostgresProfile.api._ import slick.lifted.{ ProvenShape } -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class MeetingVoiceDbModel( meetingId: String, telVoice: String, @@ -29,7 +26,7 @@ class MeetingVoiceDbTableDef(tag: Tag) extends Table[MeetingVoiceDbModel](tag, " object MeetingVoiceDAO { def insert(meetingId: String, voiceProp: VoiceProp) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingVoiceDbTableDef].forceInsert( MeetingVoiceDbModel( meetingId = meetingId, @@ -39,11 +36,6 @@ object MeetingVoiceDAO { muteOnStart = voiceProp.muteOnStart ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingVoice table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingVoice: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingWelcomeDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingWelcomeDAO.scala index 53a8b4ac5a..4872c9aebd 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingWelcomeDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/MeetingWelcomeDAO.scala @@ -4,49 +4,38 @@ import org.bigbluebutton.common2.domain.{ WelcomeProp } import slick.jdbc.PostgresProfile.api._ import slick.lifted.{ ProvenShape } -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class MeetingWelcomeDbModel( meetingId: String, - welcomeMsgTemplate: String, welcomeMsg: Option[String], welcomeMsgForModerators: Option[String] ) class MeetingWelcomeDbTableDef(tag: Tag) extends Table[MeetingWelcomeDbModel](tag, "meeting_welcome") { val meetingId = column[String]("meetingId", O.PrimaryKey) - val welcomeMsgTemplate = column[String]("welcomeMsgTemplate") val welcomeMsg = column[Option[String]]("welcomeMsg") val welcomeMsgForModerators = column[Option[String]]("welcomeMsgForModerators") // def fk_meetingId: ForeignKeyQuery[MeetingDbTableDef, MeetingDbModel] = foreignKey("fk_meetingId", meetingId, TableQuery[MeetingDbTableDef])(_.meetingId) - override def * : ProvenShape[MeetingWelcomeDbModel] = (meetingId, welcomeMsgTemplate, welcomeMsg, welcomeMsgForModerators) <> (MeetingWelcomeDbModel.tupled, MeetingWelcomeDbModel.unapply) + override def * : ProvenShape[MeetingWelcomeDbModel] = (meetingId, welcomeMsg, welcomeMsgForModerators) <> (MeetingWelcomeDbModel.tupled, MeetingWelcomeDbModel.unapply) } object MeetingWelcomeDAO { def insert(meetingId: String, welcomeProp: WelcomeProp) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[MeetingWelcomeDbTableDef].forceInsert( MeetingWelcomeDbModel( meetingId = meetingId, - welcomeMsgTemplate = welcomeProp.welcomeMsgTemplate, welcomeMsg = welcomeProp.welcomeMsg match { case "" => None case m => Some(m) }, - welcomeMsgForModerators = welcomeProp.modOnlyMessage match { + welcomeMsgForModerators = welcomeProp.welcomeMsgForModerators match { case "" => None case m => Some(m) } ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in MeetingWelcome table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting MeetingWelcome: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/NotificationDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/NotificationDAO.scala index 7d9dc9fc50..5f5ca2d06e 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/NotificationDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/NotificationDAO.scala @@ -3,9 +3,6 @@ import org.bigbluebutton.common2.msgs.{BbbCommonEnvCoreMsg, NotifyAllInMeetingEv import PostgresProfile.api._ import spray.json.JsValue -import scala.util.{Failure, Success} -import scala.concurrent.ExecutionContext.Implicits.global - case class NotificationDbModel( // notificationId: String, meetingId: String, @@ -49,7 +46,7 @@ object NotificationDAO { } if (notificationType != "") { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[NotificationDbTableDef].forceInsert( NotificationDbModel( meetingId, @@ -67,10 +64,7 @@ object NotificationDAO { createdAt = new java.sql.Timestamp(System.currentTimeMillis()) ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted/updated on Notification table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting/updating Notification: $e") - } + ) } } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PluginDataChannelEntryDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PluginDataChannelEntryDAO.scala index ca4c47e2dd..efb51cc880 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PluginDataChannelEntryDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PluginDataChannelEntryDAO.scala @@ -2,11 +2,9 @@ package org.bigbluebutton.core.db import PostgresProfile.api._ import org.bigbluebutton.core.db.DatabaseConnection.{db, logger} +import org.bigbluebutton.core.util.RandomStringGenerator import spray.json.JsValue - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.{Await, Future} -import scala.util.{Failure, Success} +import scala.concurrent.{Await} import scala.concurrent.duration.Duration object Permission { @@ -18,9 +16,9 @@ case class PluginDataChannelEntryDbModel( pluginName: String, channelName: String, subChannelName: String, -// entryId: Option[String] = None, + entryId: Option[String] = None, payloadJson: JsValue, - fromUserId: String, + createdBy: String, toRoles: Option[List[String]], toUserIds: Option[List[String]], createdAt: java.sql.Timestamp, @@ -32,27 +30,29 @@ class PluginDataChannelEntryDbTableDef(tag: Tag) extends Table[PluginDataChannel val pluginName = column[String]("pluginName", O.PrimaryKey) val channelName = column[String]("channelName", O.PrimaryKey) val subChannelName = column[String]("subChannelName") -// val entryId = column[Option[String]]("messageId", O.PrimaryKey) //// The messageId is generated by the database + val entryId = column[Option[String]]("entryId", O.PrimaryKey) val payloadJson = column[JsValue]("payloadJson") - val fromUserId = column[String]("fromUserId") + val createdBy = column[String]("createdBy") val toRoles = column[Option[List[String]]]("toRoles") val toUserIds = column[Option[List[String]]]("toUserIds") val createdAt = column[java.sql.Timestamp]("createdAt") val deletedAt = column[Option[java.sql.Timestamp]]("deletedAt") - override def * = (meetingId, pluginName, channelName, subChannelName, payloadJson, fromUserId, toRoles, toUserIds, createdAt, deletedAt) <> (PluginDataChannelEntryDbModel.tupled, PluginDataChannelEntryDbModel.unapply) + override def * = (meetingId, pluginName, channelName, subChannelName, entryId, payloadJson, createdBy, toRoles, toUserIds, createdAt, deletedAt) <> (PluginDataChannelEntryDbModel.tupled, PluginDataChannelEntryDbModel.unapply) } object PluginDataChannelEntryDAO { - def insert(meetingId: String, pluginName: String, channelName: String, subChannelName: String, senderUserId: String, payloadJson: String, toRoles: List[String], toUserIds: List[String]) = { - DatabaseConnection.db.run( + def insert(meetingId: String, pluginName: String, channelName: String, subChannelName: String, createdBy: String, + payloadJson: Map[String, Any], toRoles: List[String], toUserIds: List[String]) = { + DatabaseConnection.enqueue( TableQuery[PluginDataChannelEntryDbTableDef].forceInsert( PluginDataChannelEntryDbModel( + entryId = Some(RandomStringGenerator.randomAlphanumericString(50)), meetingId = meetingId, pluginName = pluginName, channelName = channelName, subChannelName = subChannelName, - payloadJson = JsonUtils.stringToJson(payloadJson), - fromUserId = senderUserId, + payloadJson = JsonUtils.mapToJson(payloadJson), + createdBy = createdBy, toRoles = toRoles.map(_.toUpperCase).filter(Permission.allowedRoles.contains) match { case Nil => None case filtered => Some(filtered) @@ -62,15 +62,12 @@ object PluginDataChannelEntryDAO { deletedAt = None ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on PluginDataChannelEntry table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting PluginDataChannelEntry: $e") - } + ) } def reset(meetingId: String, pluginName: String, channelName: String, subChannelName: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PluginDataChannelEntryDbTableDef] .filter(_.meetingId === meetingId) .filter(_.pluginName === pluginName) @@ -79,15 +76,12 @@ object PluginDataChannelEntryDAO { .filter(_.deletedAt.isEmpty) .map(u => (u.deletedAt)) .update(Some(new java.sql.Timestamp(System.currentTimeMillis()))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated deleted=now() on pluginDataChannelEntry table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating deleted=now() pluginDataChannelEntry: $e") - } + ) } - def getMessageSender(meetingId: String, pluginName: String, channelName: String, - subChannelName: String, entryId: String): String = { - val query = sql"""SELECT "fromUserId" + def getEntryCreator(meetingId: String, pluginName: String, channelName: String, + subChannelName: String, entryId: String): String = { + val query = sql"""SELECT "createdBy" FROM "pluginDataChannelEntry" WHERE "deletedAt" is null AND "meetingId" = ${meetingId} @@ -107,7 +101,7 @@ object PluginDataChannelEntryDAO { def delete(meetingId: String, pluginName: String, channelName: String, subChannelName: String, entryId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( sqlu"""UPDATE "pluginDataChannelEntry" SET "deletedAt" = current_timestamp WHERE "deletedAt" is null @@ -116,10 +110,23 @@ object PluginDataChannelEntryDAO { AND "channelName" = ${channelName} AND "subChannelName" = ${subChannelName} AND "entryId" = ${entryId}""" - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated deleted=now() on pluginDataChannelEntry table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating deleted=now() pluginDataChannelEntry: $e") - } + ) + } + + def replace(meetingId: String, pluginName: String, channelName: String, + subChannelName: String, entryId: String, payloadJson: JsValue) = { + + DatabaseConnection.enqueue( + TableQuery[PluginDataChannelEntryDbTableDef] + .filter(_.meetingId === meetingId) + .filter(_.pluginName === pluginName) + .filter(_.channelName === channelName) + .filter(_.subChannelName === subChannelName) + .filter(_.entryId === entryId) + .filter(_.deletedAt.isEmpty) + .map(_.payloadJson) + .update(payloadJson) + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PollDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PollDAO.scala index 0781329004..eb44dc7644 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PollDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PollDAO.scala @@ -4,9 +4,6 @@ import org.bigbluebutton.common2.domain.SimplePollResultOutVO import org.bigbluebutton.core.models.Poll import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class PollDbModel( pollId: String, meetingId: String, @@ -39,7 +36,7 @@ object PollDAO { for { question <- poll.questions } yield { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PollDbTableDef].insertOrUpdate( PollDbModel( pollId = poll.id, @@ -54,62 +51,42 @@ object PollDAO { publishedAt = None ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on Poll table!") - - DatabaseConnection.db.run(DBIO.sequence( - for { - answer <- question.answers.toList - } yield { - PollOptionDAO.prepareOptionInsert(poll.id, answer) - } - ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on PollOption table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting PollOption: $e") - } - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting Poll: $e") + ) + DatabaseConnection.enqueue(DBIO.sequence( + for { + answer <- question.answers.toList + } yield { + PollOptionDAO.prepareOptionInsert(poll.id, answer) } + ).transactionally) } } def updateOptions(poll: SimplePollResultOutVO) = { - DatabaseConnection.db.run(DBIO.sequence( + DatabaseConnection.enqueue(DBIO.sequence( for { answer <- poll.answers.toList } yield { PollOptionDAO.prepareOptionInsertOrUpdate(poll.id, answer) } ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on PollOption table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting PollOption: $e") - } } def updatePublished(pollId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PollDbTableDef] .filter(_.pollId === pollId) .map(p => (p.published, p.publishedAt)) .update(true, Some(new java.sql.Timestamp(System.currentTimeMillis()))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated published=true on Poll table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating published=true Poll: $e") - } + ) } def updateEnded(pollId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PollDbTableDef] .filter(_.pollId === pollId) .map(p => p.ended) .update(true) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated awaitingResponses=false on Poll table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating awaitingResponses=false Poll: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PollResponseDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PollResponseDAO.scala index ddda20dac8..d831666a14 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PollResponseDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PollResponseDAO.scala @@ -3,10 +3,6 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ import org.bigbluebutton.core.models.Poll -import scala.collection.immutable.Seq -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class PollResponseDbModel( pollId: String, optionId: Option[Int], @@ -26,54 +22,45 @@ object PollResponseDAO { def insert(poll: Poll, meetingId: String, userId: String, seqOptionIds: Seq[Int]) = { //Clear previous responses of the user and add all - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PollResponseDbTableDef] .filter(_.pollId === poll.id) .filter(_.meetingId === meetingId) .filter(_.userId === userId) .delete - ).onComplete { - case Success(rowsAffected) => { - for { - optionId <- seqOptionIds - } yield { - DatabaseConnection.db.run( - TableQuery[PollResponseDbTableDef].forceInsert( - PollResponseDbModel( - pollId = poll.id, - optionId = Some(optionId), - meetingId = { - if (poll.isSecret) None else Some(meetingId) - }, - userId = { - if (poll.isSecret) None else Some(userId) - } - ) - ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on PollResponse table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting PollResponse: $e") - } - } + ) - //When Secret, insert the user in a different row just to inform the he answered already - if (poll.isSecret) { - DatabaseConnection.db.run( - TableQuery[PollResponseDbTableDef].forceInsert( - PollResponseDbModel( - pollId = poll.id, - optionId = None, - meetingId = Some(meetingId), - userId = Some(userId) - ) - ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on PollResponse(secret) table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting PollResponse(secret): $e") - } - } - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error deleting poll ${poll.id} for user ${userId}: $e") - } + for { + optionId <- seqOptionIds + } yield { + DatabaseConnection.enqueue( + TableQuery[PollResponseDbTableDef].forceInsert( + PollResponseDbModel( + pollId = poll.id, + optionId = Some(optionId), + meetingId = { + if (poll.isSecret) None else Some(meetingId) + }, + userId = { + if (poll.isSecret) None else Some(userId) + } + ) + ) + ) + } + + //When Secret, insert the user in a different row just to inform the he answered already + if (poll.isSecret) { + DatabaseConnection.enqueue( + TableQuery[PollResponseDbTableDef].forceInsert( + PollResponseDbModel( + pollId = poll.id, + optionId = None, + meetingId = Some(meetingId), + userId = Some(userId) + ) + ) + ) + } } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PostgresProfile.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PostgresProfile.scala index 4d7042dc98..8aa84994c0 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PostgresProfile.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PostgresProfile.scala @@ -1,7 +1,6 @@ package org.bigbluebutton.core.db import com.github.tminglei.slickpg._ -import org.apache.pekko.http.scaladsl.model.ParsingException import org.bigbluebutton.common2.domain.SimpleVoteOutVO import spray.json.DefaultJsonProtocol.{ StringJsonFormat, vectorFormat } import spray.json.{ JsArray, JsBoolean, JsNumber, JsObject, JsString, JsValue, JsonWriter, _ } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresAnnotationDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresAnnotationDAO.scala index 1e39188c5a..fe16e8529b 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresAnnotationDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresAnnotationDAO.scala @@ -1,9 +1,7 @@ package org.bigbluebutton.core.db import org.bigbluebutton.common2.msgs.AnnotationVO -import scala.util.{ Failure, Success } import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global case class PresAnnotationDbModel( annotationId: String, @@ -29,29 +27,27 @@ class PresAnnotationDbTableDef(tag: Tag) extends Table[PresAnnotationDbModel](ta object PresAnnotationDAO { def insertOrUpdate(meetingId: String, annotation: AnnotationVO, annotationDiff: AnnotationVO) = { - PresAnnotationHistoryDAO.insert(meetingId, annotationDiff).onComplete { - case Success(sequence) => { - DatabaseConnection.logger.debug(s"Sequence generated to PresAnnotationHistory record: $sequence") - DatabaseConnection.db.run( - TableQuery[PresAnnotationDbTableDef].insertOrUpdate( - PresAnnotationDbModel( - annotationId = annotation.id, - pageId = annotation.wbId, - meetingId = meetingId, - userId = annotation.userId, - annotationInfo = JsonUtils.mapToJson(annotation.annotationInfo).compactPrint, - lastHistorySequence = sequence.getOrElse(0), - lastUpdatedAt = new java.sql.Timestamp(System.currentTimeMillis()) - ) - ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted or updated on PresAnnotation table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting or updating PresAnnotation: $e") - } + // //TODO do it via trigger? + // PresAnnotationHistoryDAO.insert(meetingId, annotationDiff).onComplete { + // case Success(sequence) => { + // DatabaseConnection.logger.debug(s"Sequence generated to PresAnnotationHistory record: $sequence") + // + DatabaseConnection.enqueue( + TableQuery[PresAnnotationDbTableDef].insertOrUpdate( + PresAnnotationDbModel( + annotationId = annotation.id, + pageId = annotation.wbId, + meetingId = meetingId, + userId = annotation.userId, + annotationInfo = JsonUtils.mapToJson(annotation.annotationInfo).compactPrint, + lastHistorySequence = 0, + lastUpdatedAt = new java.sql.Timestamp(System.currentTimeMillis()) + ) + ) + ) - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting PresAnnotationHistory: $e") - } + // } + // case Failure(e) => DatabaseConnection.logger.error(s"Error inserting PresAnnotationHistory: $e") } def prepareInsertOrUpdate(meetingId: String, annotation: AnnotationVO) = { @@ -69,48 +65,32 @@ object PresAnnotationDAO { } def insertOrUpdateMap(meetingId: String, annotations: Array[AnnotationVO]) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( DBIO.sequence( annotations.map { annotation => prepareInsertOrUpdate(meetingId, annotation) }.toVector ).transactionally ) - .onComplete { - case Success(rowsAffected) => - DatabaseConnection.logger.debug(s"${rowsAffected.sum} row(s) inserted or updated on PresAnnotation table!") - case Failure(e) => - DatabaseConnection.logger.debug(s"Error inserting or updating PresAnnotation: $e") - } } def delete(wbId: String, meetingId: String, userId: String, annotationId: String) = { - PresAnnotationHistoryDAO.delete(wbId, meetingId, userId, annotationId).onComplete { - case Success(sequence) => { - DatabaseConnection.db.run( - TableQuery[PresAnnotationDbTableDef] - .filter(_.annotationId === annotationId) - .map(a => (a.annotationInfo, a.lastHistorySequence, a.meetingId, a.userId, a.lastUpdatedAt)) - .update("", sequence.getOrElse(0), meetingId, userId, new java.sql.Timestamp(System.currentTimeMillis())) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated annotationInfo=null on PresAnnotation table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating annotationInfo=null PresAnnotation: $e") - } - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting PresAnnotationHistory: $e") - } + // PresAnnotationHistoryDAO.delete(wbId, meetingId, userId, annotationId) + DatabaseConnection.enqueue( + TableQuery[PresAnnotationDbTableDef] + .filter(_.annotationId === annotationId) + .map(a => (a.annotationInfo, a.lastHistorySequence, a.meetingId, a.userId, a.lastUpdatedAt)) + .update("", 0, meetingId, userId, new java.sql.Timestamp(System.currentTimeMillis())) + ) } def delete(meetingId: String, userId: String, annotationIds: Array[String]) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresAnnotationDbTableDef] .filter(_.annotationId inSet annotationIds) .map(a => (a.annotationInfo, a.lastHistorySequence, a.meetingId, a.userId, a.lastUpdatedAt)) .update("", 0, meetingId, userId, new java.sql.Timestamp(System.currentTimeMillis())) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated annotationInfo=null on PresAnnotation table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating annotationInfo=null PresAnnotation: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresAnnotationHistoryDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresAnnotationHistoryDAO.scala index 2e11f2eccd..43486eecdc 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresAnnotationHistoryDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresAnnotationHistoryDAO.scala @@ -29,6 +29,7 @@ object PresAnnotationHistoryDAO { def insert(meetingId: String, annotationDiff: AnnotationVO) = { DatabaseConnection.db.run( + //TODO not being used for now TableQuery[PresAnnotationHistoryDbTableDef].returning( TableQuery[PresAnnotationHistoryDbTableDef].map(_.sequence) ) += PresAnnotationHistoryDbModel( @@ -44,6 +45,7 @@ object PresAnnotationHistoryDAO { def delete(wbId: String, meetingId: String, userId: String, annotationId: String) = { DatabaseConnection.db.run( + //TODO not being used for now TableQuery[PresAnnotationHistoryDbTableDef].returning( TableQuery[PresAnnotationHistoryDbTableDef].map(_.sequence) ) += PresAnnotationHistoryDbModel( diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageCursorDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageCursorDAO.scala index f334df2aca..2a6a19a033 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageCursorDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageCursorDAO.scala @@ -1,11 +1,7 @@ package org.bigbluebutton.core.db -import org.bigbluebutton.core.apps.whiteboard.Whiteboard import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class PresPageCursorDbModel( pageId: String, meetingId: String, @@ -30,7 +26,7 @@ class PresPageCursorDbTableDef(tag: Tag) extends Table[PresPageCursorDbModel](ta object PresPageCursorDAO { def insertOrUpdate(pageId: String, meetingId: String, userId: String, xPercent: Double, yPercent: Double) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPageCursorDbTableDef].insertOrUpdate( PresPageCursorDbModel( pageId = pageId, @@ -38,13 +34,22 @@ object PresPageCursorDAO { userId = userId, xPercent = xPercent, yPercent = yPercent, - lastUpdatedAt = new java.sql.Timestamp(System.currentTimeMillis(), + lastUpdatedAt = new java.sql.Timestamp(System.currentTimeMillis()), ) ) - )).onComplete { - case Success(rowsAffected) => // DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on pres_page_cursor table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting pres_page_cursor: $e") + ) + } + + def clearUnusedCursors(meetingId: String, pageId: String, enabledUsers: Array[String]): Unit = { + val deleteQuery = TableQuery[PresPageCursorDbTableDef] + .filter(_.pageId === pageId) + + if(enabledUsers.length > 0) { + deleteQuery.filter(_.meetingId === meetingId) + deleteQuery.filterNot(_.userId inSet enabledUsers) } + + DatabaseConnection.enqueue(deleteQuery.delete) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageDAO.scala index 4a12aa20d4..43733ff0be 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageDAO.scala @@ -1,12 +1,11 @@ package org.bigbluebutton.core.db -import org.bigbluebutton.core.models.{ PresentationInPod, PresentationPage } +import org.bigbluebutton.core.models.{PresentationInPod, PresentationPage} import PostgresProfile.api._ import spray.json.JsValue import spray.json._ - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } +import scala.util.{Success, Failure} +import scala.concurrent.ExecutionContext case class PresPageDbModel( pageId: String, @@ -26,7 +25,8 @@ case class PresPageDbModel( viewBoxHeight: Double, maxImageWidth: Int, maxImageHeight: Int, - uploadCompleted: Boolean + uploadCompleted: Boolean, + infiniteWhiteboard: Boolean, ) class PresPageDbTableDef(tag: Tag) extends Table[PresPageDbModel](tag, None, "pres_page") { @@ -48,18 +48,24 @@ class PresPageDbTableDef(tag: Tag) extends Table[PresPageDbModel](tag, None, "pr val maxImageWidth = column[Int]("maxImageWidth") val maxImageHeight = column[Int]("maxImageHeight") val uploadCompleted = column[Boolean]("uploadCompleted") - // val presentation = foreignKey("presentation_fk", presentationId, Presentations)(_.presentationId, onDelete = ForeignKeyAction.Cascade) - def * = (pageId, presentationId, num, urlsJson, content, slideRevealed, current, xOffset, yOffset, widthRatio, heightRatio, width, height, viewBoxWidth, viewBoxHeight, maxImageWidth, maxImageHeight, uploadCompleted) <> (PresPageDbModel.tupled, PresPageDbModel.unapply) + val infiniteWhiteboard = column[Boolean]("infiniteWhiteboard") + + def * = ( + pageId, presentationId, num, urlsJson, content, slideRevealed, current, xOffset, yOffset, widthRatio, heightRatio, width, height, viewBoxWidth, viewBoxHeight, maxImageWidth, maxImageHeight, uploadCompleted, infiniteWhiteboard + ) <> (PresPageDbModel.tupled, PresPageDbModel.unapply) } object PresPageDAO { + implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.global + implicit val mapFormat: JsonWriter[Map[String, String]] = new JsonWriter[Map[String, String]] { def write(m: Map[String, String]): JsValue = { JsObject(m.map { case (k, v) => k -> JsString(v) }) } } + def insert(presentationId: String, page: PresentationPage) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPageDbTableDef].insertOrUpdate( PresPageDbModel( pageId = page.id, @@ -79,49 +85,50 @@ object PresPageDAO { viewBoxHeight = 1, maxImageWidth = 1440, maxImageHeight = 1080, - uploadCompleted = page.converted + uploadCompleted = page.converted, + infiniteWhiteboard = page.infiniteWhiteboard, ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on PresentationPage table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting PresentationPage: $e") - } + ) } def setCurrentPage(presentation: PresentationInPod, pageId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( sqlu"""UPDATE pres_page SET - "current" = (case when "pageId" = ${pageId} then true else false end), - "slideRevealed" = (case when "pageId" = ${pageId} then true else "slideRevealed" end) + "current" = (case when "pageId" = $pageId then true else false end), + "slideRevealed" = (case when "pageId" = $pageId then true else "slideRevealed" end) WHERE "presentationId" = ${presentation.id}""" - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated current on PresPage table") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating current on PresPage: $e") - } + ) } def resizeAndMovePage(presentation: PresentationPage) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPageDbTableDef] .filter(_.pageId === presentation.id) .map(p => (p.xOffset, p.yOffset, p.widthRatio, p.heightRatio)) .update((presentation.xOffset, presentation.yOffset, presentation.widthRatio, presentation.heightRatio)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated size on PresPage table") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating size on PresPage: $e") - } + ) } def updateSlidePosition(pageId: String, width: Double, height: Double, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPageDbTableDef] .filter(_.pageId === pageId) .map(p => (p.width, p.height, p.xOffset, p.yOffset, p.viewBoxWidth, p.viewBoxHeight)) .update((width, height, xOffset, yOffset, widthRatio, heightRatio)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated slide position on PresPage table") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating slide position on PresPage: $e") - } + ) } -} \ No newline at end of file + + def updateInfiniteWhiteboard(pageId: String, infiniteWhiteboard: Boolean) = { + DatabaseConnection.db.run( + TableQuery[PresPageDbTableDef] + .filter(_.pageId === pageId) + .map(p => p.infiniteWhiteboard) + .update(infiniteWhiteboard) + ).onComplete { + case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated infiniteWhiteboard on PresPage table") + case Failure(e) => DatabaseConnection.logger.debug(s"Error updating infiniteWhiteboard on PresPage: $e") + } + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageWritersDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageWritersDAO.scala index 57bbf738f5..3a1c6a9737 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageWritersDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPageWritersDAO.scala @@ -3,9 +3,6 @@ package org.bigbluebutton.core.db import org.bigbluebutton.core.apps.whiteboard.Whiteboard import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success} - case class PresPageWritersDbModel( pageId: String, meetingId: String, @@ -34,15 +31,14 @@ object PresPageWritersDAO { deleteQuery.filterNot(_.userId inSet whiteboard.multiUser) } - DatabaseConnection.db.run(deleteQuery.delete).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"Users deleted from pres_page_writers ${whiteboard.id}") - case Failure(e) => DatabaseConnection.logger.error(s"Error deleting users from pres_page_writers: $e") - } + DatabaseConnection.enqueue(deleteQuery.delete) + + PresPageCursorDAO.clearUnusedCursors(meetingId, whiteboard.id, whiteboard.multiUser) for { userId <- whiteboard.multiUser } yield { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPageWritersDbTableDef].insertOrUpdate( PresPageWritersDbModel( pageId = whiteboard.id, @@ -51,12 +47,7 @@ object PresPageWritersDAO { changedModeOn = whiteboard.changedModeOn ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on pres_page_writers table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting pres_page_writers: $e") - } + ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPresentationDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPresentationDAO.scala index 813d4b790b..cb8abd892e 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPresentationDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/PresPresentationDAO.scala @@ -4,13 +4,8 @@ import PostgresProfile.api._ import org.bigbluebutton.core.models.PresentationInPod import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success} import spray.json._ -import scala.concurrent.Future - - - case class PresPresentationDbModel( presentationId: String, meetingId: String, @@ -75,7 +70,7 @@ object PresPresentationDAO { } def insertToken(meetingId: String, userId: String, temporaryId: String, presentationId: String, uploadToken: String, filename: String) = { - val dbRun = DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPresentationDbTableDef].forceInsert( PresPresentationDbModel( presentationId = presentationId, @@ -102,64 +97,48 @@ object PresPresentationDAO { ) ) ) - - dbRun.onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on Presentation table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting Presentation: $e") - } - - dbRun } def updateConversionStarted(meetingId: String, presentation: PresentationInPod) = { - val checkAndInsert = DatabaseConnection.db.run( - TableQuery[PresPresentationDbTableDef] - .filter(_.presentationId === presentation.id).exists.result).flatMap { exists => - if (!exists) { - insertToken(meetingId, "", "", presentation.id, "", presentation.name) - } else { - Future.successful(0) - } - } + val presentationQuery = TableQuery[PresPresentationDbTableDef].filter(_.presentationId === presentation.id) + DatabaseConnection.db.run(presentationQuery.exists.result).map { exists => + if (!exists) { + insertToken(meetingId, "", "", presentation.id, "", presentation.name) + } - checkAndInsert.flatMap { _ => - DatabaseConnection.db.run( - TableQuery[PresPresentationDbTableDef] - .filter(_.presentationId === presentation.id) - .map(p => ( - p.name, - p.filenameConverted, - p.isDefault, - p.downloadable, - p.downloadFileExtension, - p.removable, - p.uploadInProgress, - p.uploadCompleted, - p.totalPages)) - .update( - (presentation.name, - presentation.filenameConverted, - presentation.default, - presentation.downloadable, - presentation.downloadFileExtension match { - case "" => None - case downloadFileExtension => Some(downloadFileExtension) - }, - presentation.removable, - !presentation.uploadCompleted, - presentation.uploadCompleted, - presentation.numPages - )) - ) - }.onComplete { - case Success(rowAffected) => DatabaseConnection.logger.debug(s"$rowAffected row(s) updated basicData on PresPresentation table") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating basicData on PresPresentation: $e") + DatabaseConnection.enqueue( + presentationQuery.map(p => ( + p.name, + p.filenameConverted, + p.isDefault, + p.downloadable, + p.downloadFileExtension, + p.removable, + p.uploadInProgress, + p.uploadCompleted, + p.totalPages, + p.uploadErrorMsgKey, + p.uploadErrorDetailsJson + )) + .update( + presentation.name, + presentation.filenameConverted, + presentation.default, + presentation.downloadable, + if (presentation.downloadFileExtension.isEmpty) None else Some(presentation.downloadFileExtension), + presentation.removable, + !presentation.uploadCompleted, + presentation.uploadCompleted, + presentation.numPages, + if (presentation.errorMsgKey.isEmpty) None else Some(presentation.errorMsgKey), + if (presentation.errorDetails.isEmpty) None else Some(presentation.errorDetails.toJson) + )) } } def updatePages(presentation: PresentationInPod) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPresentationDbTableDef] .filter(_.presentationId === presentation.id) .map(p => (p.downloadFileExtension, p.uploadInProgress, p.uploadCompleted, p.totalPages)) @@ -172,134 +151,104 @@ object PresPresentationDAO { presentation.uploadCompleted, presentation.numPages, )) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on PresPresentation table!") + ) - DatabaseConnection.db.run(DBIO.sequence( - for { - page <- presentation.pages - } yield { - TableQuery[PresPageDbTableDef].insertOrUpdate( - PresPageDbModel( - pageId = page._2.id, - presentationId = presentation.id, - num = page._2.num, - urlsJson = page._2.urls.toJson, - content = page._2.content, - slideRevealed = page._2.current, - current = page._2.current, - xOffset = page._2.xOffset, - yOffset = page._2.yOffset, - widthRatio = page._2.widthRatio, - heightRatio = page._2.heightRatio, - width = page._2.width, - height = page._2.height, - viewBoxWidth = 1, - viewBoxHeight = 1, - maxImageWidth = 1440, - maxImageHeight = 1080, - uploadCompleted = page._2.converted - ) - ) - } - ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on PresentationPage table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating PresentationPage: $e") - } - - //Set current - if (presentation.current) { - setCurrentPres(presentation.id) + DatabaseConnection.enqueue(DBIO.sequence( + for { + page <- presentation.pages + } yield { + TableQuery[PresPageDbTableDef].insertOrUpdate( + PresPageDbModel( + pageId = page._2.id, + presentationId = presentation.id, + num = page._2.num, + urlsJson = page._2.urls.toJson, + content = page._2.content, + slideRevealed = page._2.current, + current = page._2.current, + xOffset = page._2.xOffset, + yOffset = page._2.yOffset, + widthRatio = page._2.widthRatio, + heightRatio = page._2.heightRatio, + width = page._2.width, + height = page._2.height, + viewBoxWidth = 1, + viewBoxHeight = 1, + maxImageWidth = 1440, + maxImageHeight = 1080, + uploadCompleted = page._2.converted, + infiniteWhiteboard = page._2.infiniteWhiteboard, + ) + ) } + ).transactionally) - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating user: $e") + //Set current + if (presentation.current) { + setCurrentPres(presentation.id) } } def setCurrentPres(presentationId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( sqlu"""UPDATE pres_presentation SET "current" = (case when "presentationId" = ${presentationId} then true else false end) WHERE "meetingId" = (select "meetingId" from pres_presentation where "presentationId" = ${presentationId}) AND exists (select 1 from pres_page where "presentationId" = ${presentationId} AND "current" IS true)""" - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated current on PresPresentation table") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating current on PresPresentation: $e") - } + ) } def updateDownloadable(presentationId: String, downloadable : Boolean, downloadableExtension: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPresentationDbTableDef] .filter(_.presentationId === presentationId) .map(p => (p.downloadable, p.downloadFileExtension)) .update((downloadable, Some(downloadableExtension))) - ).onComplete { - case Success(rowAffected) => DatabaseConnection.logger.debug(s"$rowAffected row(s) updated downloadable on PresPresentation table") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating downloadable on PresPresentation: $e") - } + ) } def updateDownloadUri(presentationId: String, downloadFileUri: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPresentationDbTableDef] .filter(_.presentationId === presentationId) .map(p => p.downloadFileUri) .update(Some(downloadFileUri)) - ).onComplete { - case Success(rowAffected) => DatabaseConnection.logger.debug(s"$rowAffected row(s) updated originalFileURI on PresPresentation table") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating originalFileURI on PresPresentation: $e") - } + ) } def updateErrors(presentationId: String, errorMsgKey: String, errorDetails: scala.collection.immutable.Map[String, String]) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPresentationDbTableDef] .filter(_.presentationId === presentationId) .map(p => (p.uploadErrorMsgKey, p.uploadErrorDetailsJson)) .update(Some(errorMsgKey), Some(errorDetails.toJson)) - ).onComplete { - case Success(rowAffected) => DatabaseConnection.logger.debug(s"$rowAffected row(s) updated errorMsgKey on PresPresentation table") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating errorMsgKey on PresPresentation: $e") - } + ) } def updateExportToChat(presentationId: String, exportToChatStatus: String, exportToChatCurrentPage: Int, exportToChatHasError: Boolean) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPresentationDbTableDef] .filter(_.presentationId === presentationId) .map(p => (p.exportToChatStatus, p.exportToChatCurrentPage, p.exportToChatHasError)) .update(Some(exportToChatStatus), Some(exportToChatCurrentPage), Some(exportToChatHasError)) - ).onComplete { - case Success(rowAffected) => DatabaseConnection.logger.debug(s"$rowAffected row(s) updated exportToChat on PresPresentation table") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating exportToChat on PresPresentation: $e") - } + ) } def updateExportToChatStatus(presentationId: String, exportToChatStatus: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPresentationDbTableDef] .filter(_.presentationId === presentationId) .map(p => p.exportToChatStatus) .update(Some(exportToChatStatus)) - ).onComplete { - case Success(rowAffected) => DatabaseConnection.logger.debug(s"$rowAffected row(s) updated exportToChatStatus on PresPresentation table") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating exportToChatStatus on PresPresentation: $e") - } + ) } def delete(presentationId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[PresPresentationDbTableDef] .filter(_.presentationId === presentationId) .delete - ).onComplete { - case Success(rowAffected) => DatabaseConnection.logger.debug(s"$rowAffected row(s) deleted presentation on PresPresentation table") - case Failure(e) => DatabaseConnection.logger.error(s"Error deleting presentation on PresPresentation: $e") - } + ) } -} +} \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ScreenshareDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ScreenshareDAO.scala index 17cb4fe36f..668e913486 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ScreenshareDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/ScreenshareDAO.scala @@ -6,9 +6,6 @@ import org.bigbluebutton.core.util.RandomStringGenerator import slick.jdbc.PostgresProfile.api._ import slick.lifted.ProvenShape -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class ScreenshareDbModel( screenshareId: String, meetingId: String, @@ -40,7 +37,7 @@ class ScreenshareDbTableDef(tag: Tag) extends Table[ScreenshareDbModel](tag, "sc object ScreenshareDAO { def insert(meetingId: String, screenshareModel: ScreenshareModel) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ScreenshareDbTableDef].forceInsert( ScreenshareDbModel( screenshareId = System.currentTimeMillis() + "-" + RandomStringGenerator.randomAlphanumericString(8), @@ -56,24 +53,18 @@ object ScreenshareDAO { stoppedAt = None ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in Screenshare table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting Screenshare: $e") - } + ) } def updateStopped(meetingId: String, stream: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[ScreenshareDbTableDef] .filter(_.meetingId === meetingId) .filter(_.stream === stream) .filter(_.stoppedAt.isEmpty) .map(ev => ev.stoppedAt) .update(Some(new java.sql.Timestamp(System.currentTimeMillis()))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated stoppedAt on Screenshare table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating stoppedAt on Screenshare: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesDAO.scala index 037da3090c..5abdf8bfe6 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesDAO.scala @@ -2,9 +2,6 @@ package org.bigbluebutton.core.db import org.bigbluebutton.core.models.PadGroup import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class SharedNotesDbModel( meetingId: String, sharedNotesExtId: String, @@ -28,7 +25,7 @@ class SharedNotesDbTableDef(tag: Tag) extends Table[SharedNotesDbModel](tag, Non object SharedNotesDAO { def insert(meetingId: String, group: PadGroup, padId: String, name: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[SharedNotesDbTableDef].insertOrUpdate( SharedNotesDbModel( meetingId = meetingId, @@ -39,22 +36,16 @@ object SharedNotesDAO { pinned = false ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on SharedNotes table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting SharedNotes: $e") - } + ) } def updatePinned(meetingId: String, sharedNotesExtId: String, pinned: Boolean) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[SharedNotesDbTableDef] .filter(_.meetingId === meetingId) .filter(_.sharedNotesExtId === sharedNotesExtId) .map(n => n.pinned) .update(pinned) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated pinned on SharedNotes table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating pinned SharedNotes: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesRevDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesRevDAO.scala index 06529cd706..eff5eec2ef 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesRevDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesRevDAO.scala @@ -2,9 +2,6 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class SharedNotesRevDbModel( meetingId: String, sharedNotesExtId: String, @@ -32,7 +29,7 @@ class SharedNotesRevDbTableDef(tag: Tag) extends Table[SharedNotesRevDbModel](ta object SharedNotesRevDAO { def insert(meetingId: String, sharedNotesExtId: String, revId: Int, userId: String, changeset: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[SharedNotesRevDbTableDef].insertOrUpdate( SharedNotesRevDbModel( meetingId = meetingId, @@ -46,23 +43,17 @@ object SharedNotesRevDAO { createdAt = new java.sql.Timestamp(System.currentTimeMillis()) ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on SharedNotesRev table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting SharedNotesRev: $e") - } + ) } def update(meetingId: String, sharedNotesExtId: String, revId: Int, start: Int, end: Int, text: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[SharedNotesRevDbTableDef] .filter(_.meetingId === meetingId) .filter(_.sharedNotesExtId === sharedNotesExtId) .filter(_.rev === revId) .map(n => (n.start, n.end, n.diff)) .update((Some(start), Some(end), Some(text))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated Rev on SharedNotes table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating Rev SharedNotes: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesSessionDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesSessionDAO.scala index 7527beb33e..c89296a360 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesSessionDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/SharedNotesSessionDAO.scala @@ -1,7 +1,5 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } case class SharedNotesSessionDbModel( meetingId: String, @@ -20,7 +18,7 @@ class SharedNotesSessionDbTableDef(tag: Tag) extends Table[SharedNotesSessionDbM object SharedNotesSessionDAO { def insert(meetingId: String, sharedNotesExtId: String, userId: String, sessionId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[SharedNotesSessionDbTableDef].insertOrUpdate( SharedNotesSessionDbModel( meetingId = meetingId, @@ -29,22 +27,16 @@ object SharedNotesSessionDAO { sessionId = sessionId ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on SharedNotesSession table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting SharedNotesSession: $e") - } + ) } def delete(meetingId: String, userId: String, sessionId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[SharedNotesSessionDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) .filter(_.sessionId === sessionId) .delete - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"SharedNotesSession ${sessionId} deleted") - case Failure(e) => DatabaseConnection.logger.error(s"Error deleting SharedNotesSession ${sessionId}: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/TimerDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/TimerDAO.scala index 6f5680cb4d..8241c59b1a 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/TimerDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/TimerDAO.scala @@ -1,13 +1,9 @@ package org.bigbluebutton.core.db -import org.bigbluebutton.ClientSettings.{getConfigPropertyValueByPathAsBooleanOrElse, getConfigPropertyValueByPathAsIntOrElse} import org.bigbluebutton.core.apps.TimerModel -import org.bigbluebutton.core.apps.TimerModel.{getAccumulated, getEndedAt, getIsActive, getRunning, getStartedAt, getStopwatch, getTime, getTrack} +import org.bigbluebutton.core.apps.TimerModel.{getAccumulated, getIsActive, isRunning, getStartedAt, isStopwatch, getTime, getTrack} import slick.jdbc.PostgresProfile.api._ -import scala.util.{Failure, Success} -import scala.concurrent.ExecutionContext.Implicits.global - case class TimerDbModel( meetingId: String, stopwatch: Boolean, @@ -16,7 +12,6 @@ case class TimerDbModel( time: Long, accumulated: Long, startedOn: Long, - endedOn: Long, songTrack: String, ) @@ -28,49 +23,37 @@ class TimerDbTableDef(tag: Tag) extends Table[TimerDbModel](tag, None, "timer") val time = column[Long]("time") val accumulated = column[Long]("accumulated") val startedOn = column[Long]("startedOn") - val endedOn = column[Long]("endedOn") val songTrack = column[String]("songTrack") - override def * = (meetingId, stopwatch, running, active, time, accumulated, startedOn, endedOn, songTrack) <> (TimerDbModel.tupled, TimerDbModel.unapply) + override def * = (meetingId, stopwatch, running, active, time, accumulated, startedOn, songTrack) <> (TimerDbModel.tupled, TimerDbModel.unapply) } object TimerDAO { - def insert(meetingId: String, clientSettings: Map[String, Object]) = { - val timerEnabled = getConfigPropertyValueByPathAsBooleanOrElse(clientSettings, "public.timer.enabled", alternativeValue = true) - if(timerEnabled) { - val timerDefaultTimeInMinutes = getConfigPropertyValueByPathAsIntOrElse(clientSettings, "public.timer.time", 5) - val timerDefaultTimeInMilli = timerDefaultTimeInMinutes * 60000 - - DatabaseConnection.db.run( - TableQuery[TimerDbTableDef].insertOrUpdate( - TimerDbModel( - meetingId = meetingId, - stopwatch = true, - running = false, - active = false, - time = timerDefaultTimeInMilli, - accumulated = 0, - startedOn = 0, - endedOn = 0, - songTrack = "noTrack", - ) + def insert(meetingId: String, model: TimerModel) = { + DatabaseConnection.enqueue( + TableQuery[TimerDbTableDef].insertOrUpdate( + TimerDbModel( + meetingId = meetingId, + stopwatch = isStopwatch(model), + running = isRunning(model), + active = getIsActive(model), + time = getTime(model), + accumulated = getAccumulated(model), + startedOn = getStartedAt(model), + songTrack = getTrack(model), ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on Timer table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting Timer: $e") - } - } + ) + ) } def update(meetingId: String, timerModel: TimerModel) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[TimerDbTableDef] .filter(_.meetingId === meetingId) - .map(t => (t.stopwatch, t.running, t.active, t.time, t.accumulated, t.startedOn, t.endedOn, t.songTrack)) - .update((getStopwatch(timerModel), getRunning(timerModel), getIsActive(timerModel), getTime(timerModel), getAccumulated(timerModel), getStartedAt(timerModel), getEndedAt(timerModel), getTrack(timerModel)) + .map(t => (t.stopwatch, t.running, t.active, t.time, t.accumulated, t.startedOn, t.songTrack)) + .update( + (isStopwatch(timerModel), isRunning(timerModel), getIsActive(timerModel), getTime(timerModel), + getAccumulated(timerModel), getStartedAt(timerModel), getTrack(timerModel)) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on Timer table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating Timer: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserBreakoutRoomDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserBreakoutRoomDAO.scala index 41f88f2d47..d1660380c2 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserBreakoutRoomDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserBreakoutRoomDAO.scala @@ -3,9 +3,6 @@ package org.bigbluebutton.core.db import org.bigbluebutton.core.domain.BreakoutRoom2x import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success } - case class UserBreakoutRoomDbModel( breakoutRoomId: String, meetingId: String, @@ -31,7 +28,7 @@ class UserBreakoutRoomDbTableDef(tag: Tag) extends Table[UserBreakoutRoomDbModel object UserBreakoutRoomDAO { def updateLastBreakoutRoom(meetingId: String, userId: String, breakoutRoom: BreakoutRoom2x) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserBreakoutRoomDbTableDef].insertOrUpdate( UserBreakoutRoomDbModel( meetingId = meetingId, @@ -43,29 +40,21 @@ object UserBreakoutRoomDAO { currentlyInRoom = true ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on user_breakoutRoom table!") - } - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting user_breakoutRoom: $e") - } + ) } def updateLastBreakoutRoom(meetingId:String, usersInRoom: Vector[String], breakoutRoom: BreakoutRoom2x) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserBreakoutRoomDbTableDef] .filter(_.meetingId === meetingId) .filterNot(_.userId inSet usersInRoom) .filter(_.breakoutRoomId === breakoutRoom.id) .map(u_bk => u_bk.currentlyInRoom) .update(false) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated currentlyInRoom=false on user_breakoutRoom table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating currentlyInRoom=false on user_breakoutRoom: $e") - } + ) - DatabaseConnection.db.run(DBIO.sequence( + DatabaseConnection.enqueue(DBIO.sequence( for { userId <- usersInRoom } yield { @@ -82,9 +71,5 @@ object UserBreakoutRoomDAO { ) } ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on user_breakoutRoom table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting user_breakoutRoom: $e") - } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserCameraDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserCameraDAO.scala index 0ac0826809..2006d2cbd2 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserCameraDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserCameraDAO.scala @@ -3,9 +3,6 @@ package org.bigbluebutton.core.db import org.bigbluebutton.core.models.{ WebcamStream} import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success} - case class UserCameraDbModel( streamId: String, meetingId: String, @@ -23,7 +20,7 @@ class UserCameraDbTableDef(tag: Tag) extends Table[UserCameraDbModel](tag, None, object UserCameraDAO { def insert(meetingId: String, webcam: WebcamStream) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserCameraDbTableDef].forceInsert( UserCameraDbModel( streamId = webcam.streamId, @@ -31,23 +28,15 @@ object UserCameraDAO { userId = webcam.userId, ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on user_webcam table!") - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting webcam: $e") - } + ) } def delete(streamId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserCameraDbTableDef] .filter(_.streamId === streamId) .delete - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"Webcam ${streamId} deleted") - case Failure(e) => DatabaseConnection.logger.debug(s"Error deleting webcam: $e") - } + ) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserClientSettingsDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserClientSettingsDAO.scala index 94a3ef8e6b..57fc3896a5 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserClientSettingsDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserClientSettingsDAO.scala @@ -3,8 +3,6 @@ package org.bigbluebutton.core.db import PostgresProfile.api._ import slick.lifted.ProvenShape import spray.json.JsValue -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } case class UserClientSettingsDbModel( userId: String, @@ -21,18 +19,15 @@ class UserClientSettingsDbTableDef(tag: Tag) extends Table[UserClientSettingsDbM } object UserClientSettingsDAO { - def insert(userId: String, meetingId: String) = { - DatabaseConnection.db.run( + def insertOrUpdate(meetingId: String, userId: String, userClientSettingsJson: JsValue) = { + DatabaseConnection.enqueue( TableQuery[UserClientSettingsDbTableDef].insertOrUpdate( UserClientSettingsDbModel( userId = userId, meetingId = meetingId, - userClientSettingsJson = JsonUtils.stringToJson("{}") + userClientSettingsJson = userClientSettingsJson ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on UserClientSettings table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting UserClientSettings: $e") - } + ) } } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserConnectionStatusDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserConnectionStatusDAO.scala index d7b12c671b..6e7fa35b52 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserConnectionStatusDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserConnectionStatusDAO.scala @@ -1,9 +1,6 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class UserConnectionStatusDbModel( userId: String, meetingId: String, @@ -28,7 +25,7 @@ class UserConnectionStatusDbTableDef(tag: Tag) extends Table[UserConnectionStatu object UserConnectionStatusDAO { def insert(meetingId: String, userId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserConnectionStatusDbTableDef].insertOrUpdate( UserConnectionStatusDbModel( userId = userId, @@ -39,14 +36,11 @@ object UserConnectionStatusDAO { statusUpdatedAt = None ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on UserConnectionStatus table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting UserConnectionStatus: $e") - } + ) } def updateUserAlive(meetingId: String, userId: String, rtt: Option[Double], status: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserConnectionStatusDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) @@ -59,10 +53,7 @@ object UserConnectionStatusDAO { Some(new java.sql.Timestamp(System.currentTimeMillis())), ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated connectionAliveAt on UserConnectionStatus table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating connectionAliveAt on UserConnectionStatus: $e") - } + ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserCustomParameter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserCustomParameter.scala deleted file mode 100644 index a69ee9448f..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserCustomParameter.scala +++ /dev/null @@ -1,46 +0,0 @@ -package org.bigbluebutton.core.db - -import slick.jdbc.PostgresProfile.api._ -import slick.lifted.{ ProvenShape } - -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - -case class UserCustomParameterDbModel( - meetingId: String, - userId: String, - parameter: String, - value: String -) - -class UserCustomParameterDbTableDef(tag: Tag) extends Table[UserCustomParameterDbModel](tag, "user_customParameter") { - val meetingId = column[String]("meetingId", O.PrimaryKey) - val userId = column[String]("userId", O.PrimaryKey) - val parameter = column[String]("parameter", O.PrimaryKey) - val value = column[String]("value") - - override def * : ProvenShape[UserCustomParameterDbModel] = (meetingId, userId, parameter, value) <> (UserCustomParameterDbModel.tupled, UserCustomParameterDbModel.unapply) -} - -object UserCustomParameterDAO { - def insert(meetingId: String, userId: String, customParameters: Map[String, String]) = { - DatabaseConnection.db.run(DBIO.sequence( - for { - parameter <- customParameters - } yield { - TableQuery[UserCustomParameterDbTableDef].insertOrUpdate( - UserCustomParameterDbModel( - meetingId = meetingId, - userId = userId, - parameter = parameter._1, - value = parameter._2 - ) - ) - } - ).transactionally) - .onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on UserCustomParameter table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting UserCustomParameter: $e") - } - } -} \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserDAO.scala index 0ad66b0a72..c17d2458e8 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserDAO.scala @@ -2,9 +2,6 @@ package org.bigbluebutton.core.db import org.bigbluebutton.core.models.{RegisteredUser, VoiceUserState} import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success} - case class UserDbModel( meetingId: String, userId: String, @@ -12,6 +9,7 @@ case class UserDbModel( name: String, role: String, avatar: String = "", + webcamBackground: String = "", color: String = "", sessionToken: String = "", authToken: String = "", @@ -32,7 +30,7 @@ case class UserDbModel( class UserDbTableDef(tag: Tag) extends Table[UserDbModel](tag, None, "user") { override def * = ( - meetingId,userId,extId,name,role,avatar,color, sessionToken, authToken, authed,joined,joinErrorCode, + meetingId,userId,extId,name,role,avatar,webcamBackground,color, sessionToken, authToken, authed,joined,joinErrorCode, joinErrorMessage, banned,loggedOut,guest,guestStatus,registeredOn,excludeFromDashboard, enforceLayout) <> (UserDbModel.tupled, UserDbModel.unapply) val meetingId = column[String]("meetingId", O.PrimaryKey) val userId = column[String]("userId", O.PrimaryKey) @@ -40,6 +38,7 @@ class UserDbTableDef(tag: Tag) extends Table[UserDbModel](tag, None, "user") { val name = column[String]("name") val role = column[String]("role") val avatar = column[String]("avatar") + val webcamBackground = column[String]("webcamBackground") val color = column[String]("color") val sessionToken = column[String]("sessionToken") val authToken = column[String]("authToken") @@ -58,7 +57,7 @@ class UserDbTableDef(tag: Tag) extends Table[UserDbModel](tag, None, "user") { object UserDAO { def insert(meetingId: String, regUser: RegisteredUser) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserDbTableDef].forceInsert( UserDbModel( userId = regUser.id, @@ -68,6 +67,7 @@ object UserDAO { name = regUser.name, role = regUser.role, avatar = regUser.avatarURL, + webcamBackground = regUser.webcamBackgroundURL, color = regUser.color, sessionToken = regUser.sessionToken, authed = regUser.authed, @@ -86,88 +86,69 @@ object UserDAO { } ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in User table!") - UserConnectionStatusDAO.insert(meetingId, regUser.id) - UserCustomParameterDAO.insert(meetingId, regUser.id, regUser.customParameters) - UserClientSettingsDAO.insert(regUser.id, meetingId) - ChatUserDAO.insertUserPublicChat(meetingId, regUser.id) - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting user: $e") - } + ) + + UserConnectionStatusDAO.insert(meetingId, regUser.id) + UserMetadataDAO.insert(meetingId, regUser.id, regUser.userMetadata) + UserClientSettingsDAO.insertOrUpdate(meetingId, regUser.id, JsonUtils.stringToJson("{}")) + ChatUserDAO.insertUserPublicChat(meetingId, regUser.id) } def update(regUser: RegisteredUser) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserDbTableDef] .filter(_.meetingId === regUser.meetingId) .filter(_.userId === regUser.id) .map(u => (u.guest, u.guestStatus, u.role, u.authed, u.joined, u.banned, u.loggedOut)) .update((regUser.guest, regUser.guestStatus, regUser.role, regUser.authed, regUser.joined, regUser.banned, regUser.loggedOut)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on user table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating user: $e") - } + ) } def updateVoiceUserJoined(voiceUserState: VoiceUserState) = { - - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserDbTableDef] .filter(_.meetingId === voiceUserState.meetingId) .filter(_.userId === voiceUserState.intId) .map(u => (u.guest, u.guestStatus, u.authed, u.joined)) .update((false, "ALLOW", true, true)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on user table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating user table: $e") - } + ) } def updateJoinError(meetingId: String, userId: String, joinErrorCode: String, joinErrorMessage: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) .map(u => (u.joined, u.joinErrorCode, u.joinErrorMessage)) .update((false, Some(joinErrorCode), Some(joinErrorMessage))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on user (Joined) table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error updating user (Joined): $e") - } + ) } def softDelete(meetingId: String, userId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) + .filter(_.loggedOut =!= true) .map(u => (u.loggedOut)) .update((true)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated loggedOut=true on user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating loggedOut=true user: $e") - } + ) } def softDeleteAllFromMeeting(meetingId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserDbTableDef] .filter(_.meetingId === meetingId) .map(u => (u.loggedOut)) .update((true)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated loggedOut=true on user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating loggedOut=true user: $e") - } + ) } def transferUserToBreakoutRoomAsAudioOnly(userId: String, meetingIdFrom: String, meetingIdTo: String) = { //Create a copy of the user using the same userId, but with the meetingId of the breakoutRoom //The user will be flagged by `transferredFromParentMeeting=true` - DatabaseConnection.db.run( + DatabaseConnection.enqueue( sqlu""" WITH upsert AS ( UPDATE "user" @@ -200,34 +181,25 @@ object UserDAO { and "meetingId" = ${meetingIdFrom} and NOT EXISTS (SELECT * FROM upsert) """ - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted in user (transferredFromParentMeeting) table") - case Failure(e) => DatabaseConnection.logger.error(s"Error inserting user (transferredFromParentMeeting): $e") - } + ) //Set user as loggedOut in the old meeting (if it is from transferred origin) - DatabaseConnection.db.run( + DatabaseConnection.enqueue( sqlu"""update "user" set "loggedOut" = true where "userId" = ${userId} and "meetingId" = ${meetingIdFrom} and "transferredFromParentMeeting" is true """ - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated in user (transferredFromParentMeeting) table") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating user (transferredFromParentMeeting): $e") - } + ) } def permanentlyDeleteAllFromMeeting(meetingId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserDbTableDef] .filter(_.meetingId === meetingId) .delete - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"User from meeting ${meetingId} deleted") - case Failure(e) => DatabaseConnection.logger.error(s"Error deleting user from meeting ${meetingId}: $e") - } + ) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserGraphqlConnectionDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserGraphqlConnectionDAO.scala index e52b5b647a..81b49444b2 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserGraphqlConnectionDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserGraphqlConnectionDAO.scala @@ -1,14 +1,12 @@ package org.bigbluebutton.core.db - -import org.bigbluebutton.core.models.{ VoiceUserState } import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success } - case class UserGraphqlConnectionDbModel ( graphqlConnectionId: Option[Int], sessionToken: String, + clientSessionUUID: String, + clientType: String, + clientIsMobile: Boolean, middlewareUID: String, middlewareConnectionId: String, establishedAt: java.sql.Timestamp, @@ -17,10 +15,13 @@ case class UserGraphqlConnectionDbModel ( class UserGraphqlConnectionDbTableDef(tag: Tag) extends Table[UserGraphqlConnectionDbModel](tag, None, "user_graphqlConnection") { override def * = ( - graphqlConnectionId, sessionToken, middlewareUID, middlewareConnectionId, establishedAt, closedAt + graphqlConnectionId, sessionToken, clientSessionUUID, clientType, clientIsMobile, middlewareUID, middlewareConnectionId, establishedAt, closedAt ) <> (UserGraphqlConnectionDbModel.tupled, UserGraphqlConnectionDbModel.unapply) val graphqlConnectionId = column[Option[Int]]("graphqlConnectionId", O.PrimaryKey, O.AutoInc) val sessionToken = column[String]("sessionToken") + val clientSessionUUID = column[String]("clientSessionUUID") + val clientType = column[String]("clientType") + val clientIsMobile = column[Boolean]("clientIsMobile") val middlewareUID = column[String]("middlewareUID") val middlewareConnectionId = column[String]("middlewareConnectionId") val establishedAt = column[java.sql.Timestamp]("establishedAt") @@ -29,28 +30,31 @@ class UserGraphqlConnectionDbTableDef(tag: Tag) extends Table[UserGraphqlConnect object UserGraphqlConnectionDAO { - def insert(sessionToken: String, middlewareUID:String, middlewareConnectionId: String) = { - DatabaseConnection.db.run( + def insert(sessionToken: String, + clientSessionUUID: String, + clientType: String, + clientIsMobile: Boolean, + middlewareUID:String, + middlewareConnectionId: String) = { + DatabaseConnection.enqueue( TableQuery[UserGraphqlConnectionDbTableDef].insertOrUpdate( UserGraphqlConnectionDbModel( graphqlConnectionId = None, sessionToken = sessionToken, + clientSessionUUID = clientSessionUUID, + clientType = clientType, + clientIsMobile = clientIsMobile, middlewareUID = middlewareUID, middlewareConnectionId = middlewareConnectionId, establishedAt = new java.sql.Timestamp(System.currentTimeMillis()), closedAt = None ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on user_graphqlConnection table!") - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting user_graphqlConnection: $e") - } + ) } def updateClosed(sessionToken: String, middlewareUID: String, middlewareConnectionId: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserGraphqlConnectionDbTableDef] .filter(_.sessionToken === sessionToken) .filter(_.middlewareConnectionId === middlewareConnectionId) @@ -58,10 +62,7 @@ object UserGraphqlConnectionDAO { .filter(_.closedAt.isEmpty) .map(u => u.closedAt) .update(Some(new java.sql.Timestamp(System.currentTimeMillis()))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on user_graphqlConnection table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating user_graphqlConnection: $e") - } + ) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserMetadata.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserMetadata.scala new file mode 100644 index 0000000000..b656ac2f12 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserMetadata.scala @@ -0,0 +1,39 @@ +package org.bigbluebutton.core.db + +import slick.jdbc.PostgresProfile.api._ +import slick.lifted.{ ProvenShape } + +case class UserMetadataDbModel( + meetingId: String, + userId: String, + parameter: String, + value: String +) + +class UserMetadataDbTableDef(tag: Tag) extends Table[UserMetadataDbModel](tag, "user_metadata") { + val meetingId = column[String]("meetingId", O.PrimaryKey) + val userId = column[String]("userId", O.PrimaryKey) + val parameter = column[String]("parameter", O.PrimaryKey) + val value = column[String]("value") + + override def * : ProvenShape[UserMetadataDbModel] = (meetingId, userId, parameter, value) <> (UserMetadataDbModel.tupled, UserMetadataDbModel.unapply) +} + +object UserMetadataDAO { + def insert(meetingId: String, userId: String, userMetadata: Map[String, String]) = { + DatabaseConnection.enqueue(DBIO.sequence( + for { + metadata <- userMetadata + } yield { + TableQuery[UserMetadataDbTableDef].insertOrUpdate( + UserMetadataDbModel( + meetingId = meetingId, + userId = userId, + parameter = metadata._1, + value = metadata._2 + ) + ) + } + ).transactionally) + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserReactionDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserReactionDAO.scala index 3ed89bcd5d..feda3b2ad6 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserReactionDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserReactionDAO.scala @@ -3,9 +3,6 @@ package org.bigbluebutton.core.db import slick.jdbc.PostgresProfile.api._ import slick.lifted.{ ProvenShape } -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class UserReactionDbModel( meetingId: String, userId: String, @@ -26,7 +23,7 @@ class UserReactionDbTableDef(tag: Tag) extends Table[UserReactionDbModel](tag, " object UserReactionDAO { def insert(meetingId: String, userId: String, reactionEmoji: String, durationInSeconds: Int) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserReactionDbTableDef].forceInsert( UserReactionDbModel( meetingId = meetingId, @@ -36,10 +33,7 @@ object UserReactionDAO { createdAt = new java.sql.Timestamp(System.currentTimeMillis()) ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on UserReaction table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting UserReaction: $e") - } + ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserStateDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserStateDAO.scala index f8184daf86..33a08c658e 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserStateDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserStateDAO.scala @@ -1,15 +1,17 @@ package org.bigbluebutton.core.db -import org.bigbluebutton.core.models.{UserState} +import org.bigbluebutton.core.models.UserState import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success} - +case class UserEjectColumnsDbModel( + ejected: Boolean = false, + ejectReason: Option[String], + ejectReasonCode: Option[String], + ejectedByModerator: Option[String], +) case class UserStateDbModel( meetingId: String, userId: String, - emoji: String = "none", away: Boolean = false, raiseHand: Boolean = false, guestStatus: String, @@ -19,26 +21,24 @@ case class UserStateDbModel( clientType: String, disconnected: Boolean = false, expired: Boolean = false, - ejected: Boolean = false, - ejectReason: Option[String], - ejectReasonCode: Option[String], - ejectedByModerator: Option[String], + ejectColumns: UserEjectColumnsDbModel, presenter: Boolean = false, pinned: Boolean = false, locked: Boolean = false, speechLocale: String, + captionLocale: String, inactivityWarningDisplay: Boolean = false, inactivityWarningTimeoutSecs: Option[Long], + echoTestRunningAt: Option[java.sql.Timestamp], ) class UserStateDbTableDef(tag: Tag) extends Table[UserStateDbModel](tag, None, "user") { override def * = ( - meetingId, userId,emoji,away,raiseHand,guestStatus,guestStatusSetByModerator,guestLobbyMessage,mobile,clientType,disconnected, - expired,ejected,ejectReason,ejectReasonCode,ejectedByModerator,presenter,pinned,locked,speechLocale, - inactivityWarningDisplay, inactivityWarningTimeoutSecs) <> (UserStateDbModel.tupled, UserStateDbModel.unapply) + meetingId, userId,away,raiseHand,guestStatus,guestStatusSetByModerator,guestLobbyMessage,mobile,clientType,disconnected, + expired,ejectColumns,presenter,pinned,locked,speechLocale, captionLocale, + inactivityWarningDisplay, inactivityWarningTimeoutSecs, echoTestRunningAt) <> (UserStateDbModel.tupled, UserStateDbModel.unapply) val meetingId = column[String]("meetingId", O.PrimaryKey) val userId = column[String]("userId", O.PrimaryKey) - val emoji = column[String]("emoji") val away = column[Boolean]("away") val raiseHand = column[Boolean]("raiseHand") val guestStatus = column[String]("guestStatus") @@ -52,56 +52,61 @@ class UserStateDbTableDef(tag: Tag) extends Table[UserStateDbModel](tag, None, " val ejectReason = column[Option[String]]("ejectReason") val ejectReasonCode = column[Option[String]]("ejectReasonCode") val ejectedByModerator = column[Option[String]]("ejectedByModerator") + val ejectColumns = (ejected, ejectReason, ejectReasonCode, ejectedByModerator) <> (UserEjectColumnsDbModel.tupled, UserEjectColumnsDbModel.unapply) val presenter = column[Boolean]("presenter") val pinned = column[Boolean]("pinned") val locked = column[Boolean]("locked") val speechLocale = column[String]("speechLocale") + val captionLocale = column[String]("captionLocale") val inactivityWarningDisplay = column[Boolean]("inactivityWarningDisplay") val inactivityWarningTimeoutSecs = column[Option[Long]]("inactivityWarningTimeoutSecs") + val echoTestRunningAt = column[Option[java.sql.Timestamp]]("echoTestRunningAt") } object UserStateDAO { def update(userState: UserState) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserStateDbTableDef] .filter(_.meetingId === userState.meetingId) .filter(_.userId === userState.intId) - .map(u => (u.presenter, u.pinned, u.locked, u.speechLocale, u.emoji, u.away, u.raiseHand, u.mobile, u.clientType, u.disconnected)) - .update((userState.presenter, userState.pin, userState.locked, userState.speechLocale, userState.emoji, userState.away, userState.raiseHand, userState.mobile, userState.clientType, userState.userLeftFlag.left)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating user: $e") - } + .map(u => (u.presenter, u.pinned, u.locked, u.speechLocale, u.captionLocale, u.away, u.raiseHand, u.mobile, u.clientType, u.disconnected)) + .update(( + userState.presenter, + userState.pin, + userState.locked, + userState.speechLocale, + userState.captionLocale, + userState.away, + userState.raiseHand, + userState.mobile, + userState.clientType, + userState.userLeftFlag.left + )) + ) } def updateEjected(meetingId: String, userId: String, ejectReason: String, ejectReasonCode: String, ejectedByModerator: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserStateDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) .map(u => (u.ejected, u.ejectReason, u.ejectReasonCode, u.ejectedByModerator)) .update((true, Some(ejectReason), Some(ejectReasonCode), Some(ejectedByModerator))) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated ejected=true on user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating ejected=true user: $e") - } + ) } def updateExpired(meetingId: String, userId: String, expired: Boolean) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserStateDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) .map(u => (u.expired)) .update((expired)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated expired=true on user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating expired=true user: $e") - } + ) } def updateGuestStatus(meetingId: String, userId: String, guestStatus: String, guestStatusSetByModerator: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserStateDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) @@ -113,27 +118,21 @@ object UserStateDAO { case _ => None } )) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated guestStatus on user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating guestStatus user: $e") - } + ) } def updateGuestLobbyMessage(meetingId: String, userId: String, guestLobbyMessage: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserStateDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) .map(u => u.guestLobbyMessage) .update(Some(guestLobbyMessage)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated guestLobbyMessage on user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating guestLobbyMessage user: $e") - } + ) } def updateInactivityWarning(meetingId: String, userId: String, inactivityWarningDisplay: Boolean, inactivityWarningTimeoutSecs: Long) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserStateDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) @@ -144,10 +143,17 @@ object UserStateDAO { case timeout: Long => Some(timeout) case _ => None })) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated inactivityWarningDisplay on user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating inactivityWarningDisplay user: $e") - } + ) + } + + def updateEchoTestRunningAt(meetingId: String, userId: String) = { + DatabaseConnection.enqueue( + TableQuery[UserStateDbTableDef] + .filter(_.meetingId === meetingId) + .filter(_.userId === userId) + .map(u => (u.echoTestRunningAt)) + .update(Some(new java.sql.Timestamp(System.currentTimeMillis()))) + ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserTranscriptionErrorDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserTranscriptionErrorDAO.scala index 2834e43c28..529531364f 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserTranscriptionErrorDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserTranscriptionErrorDAO.scala @@ -1,11 +1,6 @@ package org.bigbluebutton.core.db - -import org.bigbluebutton.core.models.{ VoiceUserState } import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{ Failure, Success } - case class UserTranscriptionErrorDbModel( meetingId: String, userId: String, @@ -27,7 +22,7 @@ class UserTranscriptionErrorDbTableDef(tag: Tag) extends Table[UserTranscription object UserTranscriptionErrorDAO { def insert(userId: String, meetingId: String, errorCode: String, errorMessage: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserTranscriptionErrorDbTableDef].insertOrUpdate( UserTranscriptionErrorDbModel( meetingId = meetingId, @@ -37,10 +32,7 @@ object UserTranscriptionErrorDAO { lastUpdatedAt = new java.sql.Timestamp(System.currentTimeMillis()), ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on user_transcriptionError table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting user_transcriptionError: $e") - } + ) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserVoiceConfStateDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserVoiceConfStateDAO.scala index 31ea8d81c5..c8e1191bb2 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserVoiceConfStateDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserVoiceConfStateDAO.scala @@ -1,11 +1,6 @@ package org.bigbluebutton.core.db - -import org.bigbluebutton.core.models.{ VoiceUserState } import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success } - case class UserVoiceConfStateDbModel( meetingId: String, userId: String, @@ -29,7 +24,7 @@ class UserVoiceConfStateDbTableDef(tag: Tag) extends Table[UserVoiceConfStateDbM object UserVoiceConfStateDAO { def insertOrUpdate(meetingId: String, userId: String, voiceConf: String, voiceConfCallSession: String, clientSession: String, callState: String) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserVoiceConfStateDbTableDef].insertOrUpdate( UserVoiceConfStateDbModel( meetingId = meetingId, @@ -40,10 +35,7 @@ object UserVoiceConfStateDAO { voiceConfCallState = callState, ) ) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on user_voice table!") - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting voice: $e") - } + ) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserVoiceDAO.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserVoiceDAO.scala index c8937fb45a..1837bded60 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserVoiceDAO.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/db/UserVoiceDAO.scala @@ -1,11 +1,7 @@ package org.bigbluebutton.core.db - -import org.bigbluebutton.core.models.{ VoiceUserState } +import org.bigbluebutton.core.models.VoiceUserState import slick.jdbc.PostgresProfile.api._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.util.{Failure, Success } - case class UserVoiceDbModel( meetingId: String, userId: String, @@ -53,7 +49,7 @@ class UserVoiceDbTableDef(tag: Tag) extends Table[UserVoiceDbModel](tag, None, " object UserVoiceDAO { def insert(voiceUserState: VoiceUserState) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserVoiceDbTableDef].insertOrUpdate( UserVoiceDbModel( meetingId = voiceUserState.meetingId, @@ -73,24 +69,16 @@ object UserVoiceDAO { endTime = None ) ) - ).onComplete { - case Success(rowsAffected) => { - DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on user_voice table!") - } - case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting voice: $e") - } + ) } def update(voiceUserState: VoiceUserState) = { - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserVoiceDbTableDef] .filter(_.userId === voiceUserState.intId) .map(u => (u.listenOnly, u.muted, u.floor, u.lastFloorTime)) .update((voiceUserState.listenOnly, voiceUserState.muted, voiceUserState.floor, voiceUserState.lastFloorTime)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated on user_voice table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating user_voice: $e") - } + ) } def updateTalking(voiceUserState: VoiceUserState) = { @@ -113,23 +101,7 @@ object UserVoiceDAO { AND "userId" = ${voiceUserState.intId}""" } - DatabaseConnection.db.run(updateSql).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated with talking: ${voiceUserState.talking}") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating voice talking: $e") - } - } - - def delete(meetingId: String, userId: String) = { - DatabaseConnection.db.run( - TableQuery[UserDbTableDef] - .filter(_.meetingId === meetingId) - .filter(_.userId === userId) - .map(u => (u.loggedOut)) - .update((true)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated loggedOut=true on user table!") - case Failure(e) => DatabaseConnection.logger.error(s"Error updating loggedOut=true user: $e") - } + DatabaseConnection.enqueue(updateSql) } def deleteUserVoice(meetingId: String,userId: String) = { @@ -140,17 +112,12 @@ object UserVoiceDAO { // joined: false // spoke: false - DatabaseConnection.db.run( + DatabaseConnection.enqueue( TableQuery[UserVoiceDbTableDef] .filter(_.meetingId === meetingId) .filter(_.userId === userId) .map(u => (u.muted, u.talking, u.listenOnly, u.joined, u.spoke, u.startTime, u.endTime)) - .update((false, false, false, false, false, None, None)) - ).onComplete { - case Success(rowsAffected) => DatabaseConnection.logger.debug(s"Voice of user ${userId} deleted (joined=false)") - case Failure(e) => DatabaseConnection.logger.error(s"Error deleting voice user: $e") - } + .update((true, false, false, false, false, None, None)) + ) } - - } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/BreakoutRoom2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/BreakoutRoom2x.scala index 009a2b018d..5fa3a84e07 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/BreakoutRoom2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/BreakoutRoom2x.scala @@ -19,6 +19,8 @@ case class BreakoutRoom2x( captureSlides: Boolean, captureNotesFilename: String, captureSlidesFilename: String, + allPages: Boolean, + presId: String, ) { } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/MeetingTrackers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/MeetingTrackers.scala index 01b82a8721..0637c763fb 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/MeetingTrackers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/domain/MeetingTrackers.scala @@ -84,8 +84,7 @@ case class MeetingExpiryTracker( case class MeetingRecordingTracker( startedOnInMs: Long, - previousDurationInMs: Long, - currentDurationInMs: Long + previousDurationInMs: Long ) { def startTimer(nowInMs: Long): MeetingRecordingTracker = { @@ -93,19 +92,11 @@ case class MeetingRecordingTracker( } def pauseTimer(nowInMs: Long): MeetingRecordingTracker = { - copy(currentDurationInMs = 0L, previousDurationInMs = previousDurationInMs + nowInMs - startedOnInMs, startedOnInMs = 0L) + copy(previousDurationInMs = previousDurationInMs + nowInMs - startedOnInMs, startedOnInMs = 0L) } def resetTimer(nowInMs: Long): MeetingRecordingTracker = { - copy(startedOnInMs = nowInMs, previousDurationInMs = 0L, currentDurationInMs = 0L) - } - - def udpateCurrentDuration(nowInMs: Long): MeetingRecordingTracker = { - copy(currentDurationInMs = nowInMs - startedOnInMs) - } - - def recordingDuration(): Long = { - currentDurationInMs + previousDurationInMs + copy(startedOnInMs = nowInMs, previousDurationInMs = 0L) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/GroupChats.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/GroupChats.scala index 8c5d91b545..ad15a227c8 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/GroupChats.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/GroupChats.scala @@ -37,7 +37,8 @@ case class GroupChat(id: String, access: String, createdBy: GroupChatUser, } case class GroupChatMessage(id: String, timestamp: Long, correlationId: String, createdOn: Long, - updatedOn: Long, sender: GroupChatUser, chatEmphasizedText: Boolean = false, message: String) + updatedOn: Long, sender: GroupChatUser, chatEmphasizedText: Boolean = false, + message: String, metadata: Map[String, Any] = Map.empty) case class GroupChatWindow(windowId: String, chatIds: Vector[String], keepOpen: Boolean, openedBy: String) { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/GuestsWaiting.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/GuestsWaiting.scala index 819a83a204..a7a27bb68f 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/GuestsWaiting.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/GuestsWaiting.scala @@ -73,7 +73,7 @@ class GuestsWaiting { } } -case class GuestWaiting(intId: String, name: String, role: String, guest: Boolean, avatar: String, color: String, authenticated: Boolean, registeredOn: Long) +case class GuestWaiting(intId: String, name: String, role: String, guest: Boolean, avatar: String, webcamBackground: String, color: String, authenticated: Boolean, registeredOn: Long) case class GuestPolicy(policy: String, setBy: String) object GuestPolicyType { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Layouts.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Layouts.scala index 04758a9895..8829254765 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Layouts.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Layouts.scala @@ -74,8 +74,8 @@ class Layouts { private var pushLayout: Boolean = false; private var presentationIsOpen: Boolean = true; private var isResizing: Boolean = false; - private var cameraPosition: String = ""; - private var focusedCamera: String = ""; + private var cameraPosition: String = "contentTop"; + private var focusedCamera: String = "none"; private var presentationVideoRate: Double = 0; } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/PresentationPods.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/PresentationPods.scala index 6d9d5a54bd..f333c89a37 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/PresentationPods.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/PresentationPods.scala @@ -30,7 +30,8 @@ case class PresentationPage( heightRatio: Double = 100D, width: Double = 1440D, height: Double = 1080D, - converted: Boolean = false + converted: Boolean = false, + infiniteWhiteboard: Boolean = false, ) object PresentationInPod { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala index 25da3b4e6e..514ff12edf 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/RegisteredUsers.scala @@ -6,9 +6,9 @@ import org.bigbluebutton.core.domain.BreakoutRoom2x object RegisteredUsers { def create(meetingId: String, userId: String, extId: String, name: String, roles: String, - authToken: String, sessionToken: String, avatar: String, color: String, guest: Boolean, authenticated: Boolean, + authToken: String, sessionToken: String, avatar: String, webcamBackground: String, color: String, guest: Boolean, authenticated: Boolean, guestStatus: String, excludeFromDashboard: Boolean, enforceLayout: String, - customParameters: Map[String, String], loggedOut: Boolean): RegisteredUser = { + userMetadata: Map[String, String], loggedOut: Boolean): RegisteredUser = { new RegisteredUser( userId, extId, @@ -18,17 +18,21 @@ object RegisteredUsers { authToken, sessionToken, avatar, + webcamBackground, color, guest, authenticated, guestStatus, excludeFromDashboard, System.currentTimeMillis(), - 0, - false, - false, + lastAuthTokenValidatedOn = 0, + graphqlConnected = false, + graphqlDisconnectedOn = 0, + joined = false, + ejected = false, + banned = false, enforceLayout, - customParameters, + userMetadata, loggedOut, ) } @@ -37,6 +41,14 @@ object RegisteredUsers { users.toVector.find(u => u.authToken == token) } + def findWithSessionToken(sessionToken: String, users: RegisteredUsers): Option[RegisteredUser] = { + users.toVector.find(u => u.sessionToken == sessionToken) + } + + def findAll(users: RegisteredUsers): Vector[RegisteredUser] = { + users.toVector + } + def findWithUserId(id: String, users: RegisteredUsers): Option[RegisteredUser] = { users.toVector.find(ru => id == ru.id) } @@ -122,14 +134,16 @@ object RegisteredUsers { UserDAO.update(u) u } else { - users.delete(ejectedUser.id) -// UserDAO.softDelete(ejectedUser) it's being removed in User2x already - ejectedUser + val u = ejectedUser.modify(_.ejected).setTo(true) + users.save(u) + + updateUserJoin(users, u, joined = false) } } - def eject(id: String, users: RegisteredUsers, ban: Boolean): Option[RegisteredUser] = { + + def eject(userId: String, users: RegisteredUsers, ban: Boolean): Option[RegisteredUser] = { for { - ru <- findWithUserId(id, users) + ru <- findWithUserId(userId, users) } yield { banOrEjectUser(ru, users, ban) } @@ -172,6 +186,23 @@ object RegisteredUsers { u } + def updateUserConnectedToGraphql(users: RegisteredUsers, user: RegisteredUser, graphqlConnected: Boolean): RegisteredUser = { + val u = user.copy( + graphqlConnected = graphqlConnected, + graphqlDisconnectedOn = { + if(graphqlConnected) { + 0 + } else if(!graphqlConnected && user.graphqlDisconnectedOn == 0) { + System.currentTimeMillis() + } else { + user.graphqlDisconnectedOn + } + } + ) + users.save(u) + u + } + def setUserLoggedOutFlag(users: RegisteredUsers, user: RegisteredUser): RegisteredUser = { val u = user.copy(loggedOut = true) users.save(u) @@ -209,6 +240,7 @@ case class RegisteredUser( authToken: String, sessionToken: String, avatarURL: String, + webcamBackgroundURL: String, color: String, guest: Boolean, authed: Boolean, @@ -216,10 +248,13 @@ case class RegisteredUser( excludeFromDashboard: Boolean, registeredOn: Long, lastAuthTokenValidatedOn: Long, + graphqlConnected: Boolean, + graphqlDisconnectedOn: Long, joined: Boolean, + ejected: Boolean, banned: Boolean, enforceLayout: String, - customParameters: Map[String,String], + userMetadata: Map[String,String], loggedOut: Boolean, lastBreakoutRoom: BreakoutRoom2x = null, ) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Users2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Users2x.scala index 317cbc84e4..1c5ea6184a 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Users2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/Users2x.scala @@ -46,10 +46,10 @@ object Users2x { for { u <- findWithIntId(users, intId) } yield { - val newUser = u.copy(userLeftFlag = UserLeftFlag(false, 0)) + val newUser = u.copy(userLeftFlag = UserLeftFlag(left = false, 0)) users.save(newUser) UserStateDAO.update(newUser) - UserStateDAO.updateExpired(u.meetingId, u.intId, false) + UserStateDAO.updateExpired(u.meetingId, u.intId, expired = false) newUser } } @@ -124,6 +124,13 @@ object Users2x { newUserState } + def setClientType(users: Users2x, u: UserState, clientType: String): UserState = { + val newUserState = modify(u)(_.clientType).setTo(clientType) + users.save(newUserState) + UserStateDAO.update(newUserState) + newUserState + } + def ejectFromMeeting(users: Users2x, intId: String): Option[UserState] = { for { _ <- users.remove(intId) @@ -188,17 +195,6 @@ object Users2x { } } - def setEmojiStatus(users: Users2x, intId: String, emoji: String): Option[UserState] = { - for { - u <- findWithIntId(users, intId) - } yield { - val newUser = u.modify(_.emoji).setTo(emoji) - - users.save(newUser) - UserStateDAO.update(newUser) - newUser - } - } def setReactionEmoji(users: Users2x, intId: String, reactionEmoji: String, durationInSeconds: Int): Option[UserState] = { for { u <- findWithIntId(users, intId) @@ -256,6 +252,17 @@ object Users2x { } } + def setUserCaptionLocale(users: Users2x, intId: String, locale: String): Option[UserState] = { + for { + u <- findWithIntId(users, intId) + } yield { + val newUser = u.modify(_.captionLocale).setTo(locale) + UserStateDAO.update(newUser) + users.save(newUser) + newUser + } + } + def hasPresenter(users: Users2x): Boolean = { findPresenter(users) match { case Some(p) => true @@ -417,21 +424,24 @@ case class UserState( mobile: Boolean, authed: Boolean, guestStatus: String, - emoji: String, reactionEmoji: String, - reactionChangedOn: Long = 0, + reactionChangedOn: Long = 0, raiseHand: Boolean, away: Boolean, locked: Boolean, presenter: Boolean, avatar: String, + webcamBackground: String, color: String, - roleChangedOn: Long = System.currentTimeMillis(), - lastActivityTime: Long = System.currentTimeMillis(), - lastInactivityInspect: Long = 0, + roleChangedOn: Long = System.currentTimeMillis(), + lastActivityTime: Long = System.currentTimeMillis(), + lastInactivityInspect: Long = 0, clientType: String, userLeftFlag: UserLeftFlag, - speechLocale: String = "" + speechLocale: String = "", + captionLocale: String = "", + userMetadata: Map[String, String] = Map.empty + ) case class UserIdAndName(id: String, name: String) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala index 848a597aea..6202b0ea98 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/models/VoiceUsers.scala @@ -16,15 +16,30 @@ object VoiceUsers { users.toVector.find(u => u.uuid == uuid && u.intId == intId) } + def findWithIntIdAndCallerNum(users: VoiceUsers, intId: String, callerNum: String): Option[VoiceUserState] = { + // prlanzarin: This is a hack to allow for partial matching of callerNums. + // This is needed because the callerNums are incorrectly generated by + // FREESWITCH's ESL events when special characters are in place. + // e.g.: w_etc_0-bbbID-User;Semi (notice the semicolon) will be generated by + // FS as w_etc_0-bbbID-User (everything after the semicolon is ignored). + // We should review callerNum generation in the future as well as stop + // relying on it for session matching (use UUIDs or client session numbers instead). + users.toVector.find(u => u.intId == intId && + (u.callerNum.startsWith(callerNum) || callerNum.startsWith(u.callerNum))) + } + def findAll(users: VoiceUsers): Vector[VoiceUserState] = users.toVector def findAllNonListenOnlyVoiceUsers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.listenOnly == false) def findAllListenOnlyVoiceUsers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.listenOnly == true) def findAllFreeswitchCallers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.calledInto == "freeswitch") def findAllKurentoCallers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.calledInto == "kms") + def findAllMutedVoiceUsers(users: VoiceUsers): Vector[VoiceUserState] = users.toVector.filter(u => u.muted == true && u.listenOnly == false) def findAllBannedCallers(users: VoiceUsers): Vector[VoiceUserState] = users.bannedUsers.values.toVector + def usersInVoiceConf(users: VoiceUsers): Int = users.size + def isCallerBanned(callerIdNum: String, users: VoiceUsers): Boolean = { users.bannedUsers.contains(callerIdNum) } @@ -135,6 +150,8 @@ class VoiceUsers { private def toVector: Vector[VoiceUserState] = users.values.toVector + private def size: Int = users.size + private def ban(user: VoiceUserState): VoiceUserState = { bannedUsers += user.callerNum -> user user diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala index c2ee608a56..a72c5321df 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala @@ -55,37 +55,24 @@ class ReceivedJsonMsgHandlerActor( case CheckAlivePingSysMsg.NAME => route[CheckAlivePingSysMsg](meetingManagerChannel, envelope, jsonNode) - case GetRunningMeetingsReqMsg.NAME => - route[GetRunningMeetingsReqMsg](meetingManagerChannel, envelope, jsonNode) - case CreateMeetingReqMsg.NAME => route[CreateMeetingReqMsg](meetingManagerChannel, envelope, jsonNode) - case ValidateAuthTokenReqMsg.NAME => - routeGenericMsg[ValidateAuthTokenReqMsg](envelope, jsonNode) case RegisterUserReqMsg.NAME => // Route via meeting manager as there is a race condition if we send directly to meeting // because the meeting actor might not have been created yet. route[RegisterUserReqMsg](meetingManagerChannel, envelope, jsonNode) case UserJoinMeetingReqMsg.NAME => routeGenericMsg[UserJoinMeetingReqMsg](envelope, jsonNode) - case UserJoinMeetingAfterReconnectReqMsg.NAME => - routeGenericMsg[UserJoinMeetingAfterReconnectReqMsg](envelope, jsonNode) - case GetAllMeetingsReqMsg.NAME => - route[GetAllMeetingsReqMsg](meetingManagerChannel, envelope, jsonNode) case DestroyMeetingSysCmdMsg.NAME => route[DestroyMeetingSysCmdMsg](meetingManagerChannel, envelope, jsonNode) case EjectUserFromMeetingSysMsg.NAME => routeGenericMsg[EjectUserFromMeetingSysMsg](envelope, jsonNode) - case ValidateConnAuthTokenSysMsg.NAME => - route[ValidateConnAuthTokenSysMsg](meetingManagerChannel, envelope, jsonNode) // Guests case GetGuestsWaitingApprovalReqMsg.NAME => routeGenericMsg[GetGuestsWaitingApprovalReqMsg](envelope, jsonNode) case GuestsWaitingApprovedMsg.NAME => routeGenericMsg[GuestsWaitingApprovedMsg](envelope, jsonNode) - case GuestWaitingLeftMsg.NAME => - routeGenericMsg[GuestWaitingLeftMsg](envelope, jsonNode) case UpdatePositionInWaitingQueueReqMsg.NAME => routeGenericMsg[UpdatePositionInWaitingQueueReqMsg](envelope, jsonNode) case SetGuestPolicyCmdMsg.NAME => @@ -98,8 +85,6 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[SetPrivateGuestLobbyMessageCmdMsg](envelope, jsonNode) // Users - case GetUsersMeetingReqMsg.NAME => - routeGenericMsg[GetUsersMeetingReqMsg](envelope, jsonNode) case AddUserToPresenterGroupCmdMsg.NAME => routeGenericMsg[AddUserToPresenterGroupCmdMsg](envelope, jsonNode) case RemoveUserFromPresenterGroupCmdMsg.NAME => @@ -110,12 +95,16 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[UserActivitySignCmdMsg](envelope, jsonNode) case ChangeUserPinStateReqMsg.NAME => routeGenericMsg[ChangeUserPinStateReqMsg](envelope, jsonNode) - case ChangeUserMobileFlagReqMsg.NAME => - routeGenericMsg[ChangeUserMobileFlagReqMsg](envelope, jsonNode) case UserConnectionAliveReqMsg.NAME => routeGenericMsg[UserConnectionAliveReqMsg](envelope, jsonNode) case SetUserSpeechLocaleReqMsg.NAME => routeGenericMsg[SetUserSpeechLocaleReqMsg](envelope, jsonNode) + case SetUserCaptionLocaleReqMsg.NAME => + routeGenericMsg[SetUserCaptionLocaleReqMsg](envelope, jsonNode) + case SetUserClientSettingsReqMsg.NAME => + routeGenericMsg[SetUserClientSettingsReqMsg](envelope, jsonNode) + case SetUserEchoTestRunningReqMsg.NAME => + routeGenericMsg[SetUserEchoTestRunningReqMsg](envelope, jsonNode) case SetUserSpeechOptionsReqMsg.NAME => routeGenericMsg[SetUserSpeechOptionsReqMsg](envelope, jsonNode) @@ -158,8 +147,6 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[UpdateWebcamsOnlyForModeratorCmdMsg](envelope, jsonNode) // Pads - case PadCreateGroupReqMsg.NAME => - routeGenericMsg[PadCreateGroupReqMsg](envelope, jsonNode) case PadGroupCreatedEvtMsg.NAME => routePadMsg[PadGroupCreatedEvtMsg](envelope, jsonNode) case PadCreateReqMsg.NAME => @@ -236,6 +223,8 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[CreateBreakoutRoomsCmdMsg](envelope, jsonNode) case RequestBreakoutJoinURLReqMsg.NAME => routeGenericMsg[RequestBreakoutJoinURLReqMsg](envelope, jsonNode) + case SetBreakoutRoomInviteDismissedReqMsg.NAME => + routeGenericMsg[SetBreakoutRoomInviteDismissedReqMsg](envelope, jsonNode) case EndAllBreakoutRoomsMsg.NAME => routeGenericMsg[EndAllBreakoutRoomsMsg](envelope, jsonNode) case TransferUserToMeetingRequestMsg.NAME => @@ -261,14 +250,8 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[ChangeUserRaiseHandReqMsg](envelope, jsonNode) case ChangeUserAwayReqMsg.NAME => routeGenericMsg[ChangeUserAwayReqMsg](envelope, jsonNode) - case ChangeUserEmojiCmdMsg.NAME => - routeGenericMsg[ChangeUserEmojiCmdMsg](envelope, jsonNode) case ChangeUserReactionEmojiReqMsg.NAME => routeGenericMsg[ChangeUserReactionEmojiReqMsg](envelope, jsonNode) - case UserReactionTimeExpiredCmdMsg.NAME => - routeGenericMsg[UserReactionTimeExpiredCmdMsg](envelope, jsonNode) - case ClearAllUsersEmojiCmdMsg.NAME => - routeGenericMsg[ClearAllUsersEmojiCmdMsg](envelope, jsonNode) case ClearAllUsersReactionCmdMsg.NAME => routeGenericMsg[ClearAllUsersReactionCmdMsg](envelope, jsonNode) case ChangeUserRoleCmdMsg.NAME => @@ -295,6 +278,8 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[SetCurrentPresentationPubMsg](envelope, jsonNode) case SetCurrentPagePubMsg.NAME => routeGenericMsg[SetCurrentPagePubMsg](envelope, jsonNode) + case SetPageInfiniteWhiteboardPubMsg.NAME => + routeGenericMsg[SetPageInfiniteWhiteboardPubMsg](envelope, jsonNode) case ResizeAndMovePagePubMsg.NAME => routeGenericMsg[ResizeAndMovePagePubMsg](envelope, jsonNode) case SlideResizedPubMsg.NAME => @@ -351,10 +336,12 @@ class ReceivedJsonMsgHandlerActor( // Caption case EditCaptionHistoryPubMsg.NAME => routeGenericMsg[EditCaptionHistoryPubMsg](envelope, jsonNode) - case UpdateCaptionOwnerPubMsg.NAME => - routeGenericMsg[UpdateCaptionOwnerPubMsg](envelope, jsonNode) + case AddCaptionLocalePubMsg.NAME => + routeGenericMsg[AddCaptionLocalePubMsg](envelope, jsonNode) case SendCaptionHistoryReqMsg.NAME => routeGenericMsg[SendCaptionHistoryReqMsg](envelope, jsonNode) + case CaptionSubmitTranscriptPubMsg.NAME => + routeGenericMsg[CaptionSubmitTranscriptPubMsg](envelope, jsonNode) // Chat case GetChatHistoryReqMsg.NAME => @@ -389,8 +376,6 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[ChangeLockSettingsInMeetingCmdMsg](envelope, jsonNode) case LockUsersInMeetingCmdMsg.NAME => routeGenericMsg[LockUsersInMeetingCmdMsg](envelope, jsonNode) - case GetLockSettingsReqMsg.NAME => - routeGenericMsg[GetLockSettingsReqMsg](envelope, jsonNode) // Screenshare case ScreenshareRtmpBroadcastStartedVoiceConfEvtMsg.NAME => @@ -413,21 +398,33 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[GetGroupChatsReqMsg](envelope, jsonNode) case SendGroupChatMessageMsg.NAME => routeGenericMsg[SendGroupChatMessageMsg](envelope, jsonNode) + case SendGroupChatMessageFromApiSysPubMsg.NAME => + routeGenericMsg[SendGroupChatMessageFromApiSysPubMsg](envelope, jsonNode) case GetGroupChatMsgsReqMsg.NAME => routeGenericMsg[GetGroupChatMsgsReqMsg](envelope, jsonNode) case CreateGroupChatReqMsg.NAME => routeGenericMsg[CreateGroupChatReqMsg](envelope, jsonNode) + case SetGroupChatLastSeenReqMsg.NAME => + routeGenericMsg[SetGroupChatLastSeenReqMsg](envelope, jsonNode) + case SetGroupChatVisibleReqMsg.NAME => + routeGenericMsg[SetGroupChatVisibleReqMsg](envelope, jsonNode) //Plugin case PluginDataChannelPushEntryMsg.NAME => routeGenericMsg[PluginDataChannelPushEntryMsg](envelope, jsonNode) + case PluginDataChannelReplaceEntryMsg.NAME => + routeGenericMsg[PluginDataChannelReplaceEntryMsg](envelope, jsonNode) + case PluginDataChannelDeleteEntryMsg.NAME => routeGenericMsg[PluginDataChannelDeleteEntryMsg](envelope, jsonNode) case PluginDataChannelResetMsg.NAME => routeGenericMsg[PluginDataChannelResetMsg](envelope, jsonNode) + case PluginLearningAnalyticsDashboardSendGenericDataMsg.NAME => + routeGenericMsg[PluginLearningAnalyticsDashboardSendGenericDataMsg](envelope, jsonNode) + // ExternalVideo case StartExternalVideoPubMsg.NAME => routeGenericMsg[StartExternalVideoPubMsg](envelope, jsonNode) @@ -437,8 +434,6 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[StopExternalVideoPubMsg](envelope, jsonNode) // Timer - case CreateTimerPubMsg.NAME => - routeGenericMsg[CreateTimerPubMsg](envelope, jsonNode) case ActivateTimerReqMsg.NAME => routeGenericMsg[ActivateTimerReqMsg](envelope, jsonNode) case DeactivateTimerReqMsg.NAME => @@ -455,8 +450,6 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[ResetTimerReqMsg](envelope, jsonNode) case SetTrackReqMsg.NAME => routeGenericMsg[SetTrackReqMsg](envelope, jsonNode) - case TimerEndedPubMsg.NAME => - routeGenericMsg[TimerEndedPubMsg](envelope, jsonNode) // Messages from Graphql Middleware case UserGraphqlConnectionEstablishedSysMsg.NAME => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/record/events/ParticipantJoinRecordEvent.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/record/events/ParticipantJoinRecordEvent.scala index 230bd38103..1b10e32b9a 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/record/events/ParticipantJoinRecordEvent.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/record/events/ParticipantJoinRecordEvent.scala @@ -19,8 +19,11 @@ package org.bigbluebutton.core.record.events +import spray.json._ + class ParticipantJoinRecordEvent extends AbstractParticipantRecordEvent { import ParticipantJoinRecordEvent._ + import ParticipantJoinRecordEventJsonProtocol._ setEvent("ParticipantJoinEvent") @@ -43,6 +46,10 @@ class ParticipantJoinRecordEvent extends AbstractParticipantRecordEvent { def setRole(role: String) { eventMap.put(ROLE, role) } + + def setUserdata(userMetadata: Map[String, String]): Unit = { + eventMap.put(USER_DATA, userMetadata.toJson.compactPrint) + } } object ParticipantJoinRecordEvent { @@ -50,4 +57,9 @@ object ParticipantJoinRecordEvent { protected final val EXT_USER_ID = "externalUserId" protected final val NAME = "name" protected final val ROLE = "role" + protected final val USER_DATA = "userdata" +} + +object ParticipantJoinRecordEventJsonProtocol extends DefaultJsonProtocol { + } \ No newline at end of file diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala index 50d71ebb29..8011362f27 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/HandlerHelpers.scala @@ -40,7 +40,7 @@ trait HandlerHelpers extends SystemConfiguration { } } - def userJoinMeeting(outGW: OutMsgRouter, authToken: String, clientType: String, + def userJoinMeeting(outGW: OutMsgRouter, authToken: String, clientType: String, mobile: Boolean, liveMeeting: LiveMeeting, state: MeetingState2x): MeetingState2x = { val nu = for { @@ -63,18 +63,19 @@ trait HandlerHelpers extends SystemConfiguration { guest = regUser.guest, authed = regUser.authed, guestStatus = regUser.guestStatus, - emoji = "none", reactionEmoji = "none", raiseHand = false, away = false, pin = false, - mobile = false, + mobile = mobile, presenter = false, locked = MeetingStatus2x.getPermissions(liveMeeting.status).lockOnJoin, avatar = regUser.avatarURL, + webcamBackground = regUser.webcamBackgroundURL, color = regUser.color, clientType = clientType, - userLeftFlag = UserLeftFlag(false, 0) + userLeftFlag = UserLeftFlag(false, 0), + userMetadata = regUser.userMetadata ) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index 35bc14170c..a31d33900b 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -28,21 +28,19 @@ import org.bigbluebutton.core.models.{ Users2x, VoiceUsers, _ } import org.bigbluebutton.core2.{ MeetingStatus2x, Permissions } import org.bigbluebutton.core2.message.handlers._ import org.bigbluebutton.core2.message.handlers.meeting._ -import org.bigbluebutton.common2.msgs.{ PluginDataChannelDeleteEntryMsgBody, _ } +import org.bigbluebutton.common2.msgs._ import org.bigbluebutton.core.apps.breakout._ import org.bigbluebutton.core.apps.polls._ import org.bigbluebutton.core.apps.voice._ import org.apache.pekko.actor.Props import org.apache.pekko.actor.OneForOneStrategy -import org.bigbluebutton.ClientSettings.{ getConfigPropertyValueByPathAsBooleanOrElse, getConfigPropertyValueByPathAsStringOrElse } +import org.bigbluebutton.ClientSettings.{ getConfigPropertyValueByPathAsBooleanOrElse, getConfigPropertyValueByPathAsIntOrElse, getConfigPropertyValueByPathAsStringOrElse } import org.bigbluebutton.common2.msgs - import scala.concurrent.duration._ import org.bigbluebutton.core.apps.layout.LayoutApp2x -import org.bigbluebutton.core.apps.meeting.{ SyncGetMeetingInfoRespMsgHdlr, ValidateConnAuthTokenSysMsgHdlr } import org.bigbluebutton.core.apps.plugin.PluginHdlrs import org.bigbluebutton.core.apps.users.ChangeLockSettingsInMeetingCmdMsgHdlr -import org.bigbluebutton.core.db.{ MeetingDAO, NotificationDAO, UserStateDAO } +import org.bigbluebutton.core.db.{ MeetingDAO, NotificationDAO, TimerDAO, UserStateDAO } import org.bigbluebutton.core.models.VoiceUsers.{ findAllFreeswitchCallers, findAllListenOnlyVoiceUsers } import org.bigbluebutton.core.models.Webcams.findAll import org.bigbluebutton.core2.MeetingStatus2x.hasAuthedUserJoined @@ -76,7 +74,6 @@ class MeetingActor( with UsersApp2x with UserJoinMeetingReqMsgHdlr - with UserJoinMeetingAfterReconnectReqMsgHdlr with UserEstablishedGraphqlConnectionInternalMsgHdlr with UserConnectedToGlobalAudioMsgHdlr with UserDisconnectedFromGlobalAudioMsgHdlr @@ -91,17 +88,13 @@ class MeetingActor( with EjectUserFromVoiceCmdMsgHdlr with EndMeetingSysCmdMsgHdlr with DestroyMeetingSysCmdMsgHdlr - with SendTimeRemainingUpdateHdlr - with SendBreakoutTimeRemainingMsgHdlr - with SendBreakoutTimeRemainingInternalMsgHdlr with ChangeLockSettingsInMeetingCmdMsgHdlr - with SyncGetMeetingInfoRespMsgHdlr with ClientToServerLatencyTracerMsgHdlr - with ValidateConnAuthTokenSysMsgHdlr with UserActivitySignCmdMsgHdlr { object CheckVoiceRecordingInternalMsg object SyncVoiceUserStatusInternalMsg + object MeetingTasksExecutor object MeetingInfoAnalyticsMsg object MeetingInfoAnalyticsLogMsg @@ -161,7 +154,7 @@ class MeetingActor( endWhenNoModeratorDelayInMs = TimeUtil.minutesToMillis(props.durationProps.endWhenNoModeratorDelayInMinutes) ) - val recordingTracker = new MeetingRecordingTracker(startedOnInMs = 0L, previousDurationInMs = 0L, currentDurationInMs = 0L) + val recordingTracker = new MeetingRecordingTracker(startedOnInMs = 0L, previousDurationInMs = 0L) var state = new MeetingState2x( new GroupChats(Map.empty), @@ -209,6 +202,7 @@ class MeetingActor( initLockSettings(liveMeeting, liveMeeting.props.lockSettingsProps) initSharedNotes(liveMeeting) + initTimer(liveMeeting) /** *****************************************************************/ // Helper to create fake users for testing (ralam jan 5, 2018) @@ -243,6 +237,13 @@ class MeetingActor( MeetingInfoAnalyticsMsg ) + context.system.scheduler.schedule( + 5 seconds, + 5 seconds, + self, + MeetingTasksExecutor + ) + def receive = { case SyncVoiceUserStatusInternalMsg => checkVoiceConfUsersStatus() @@ -252,6 +253,8 @@ class MeetingActor( handleMeetingInfoAnalyticsLogging() case MeetingInfoAnalyticsMsg => handleMeetingInfoAnalyticsService() + case MeetingTasksExecutor => + handleMeetingTasksExecutor() //============================= // 2x messages @@ -260,9 +263,9 @@ class MeetingActor( // Handling RegisterUserReqMsg as it is forwarded from BBBActor and // its type is not BbbCommonEnvCoreMsg case m: RegisterUserReqMsg => usersApp.handleRegisterUserReqMsg(m) - case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m) - case m: GetRunningMeetingStateReqMsg => handleGetRunningMeetingStateReqMsg(m) - case m: ValidateConnAuthTokenSysMsg => handleValidateConnAuthTokenSysMsg(m) + + //API Msgs + case m: GetUserApiMsg => usersApp.handleGetUserApiMsg(m, sender) // Meeting case m: DestroyMeetingSysCmdMsg => handleDestroyMeetingSysCmdMsg(m) @@ -272,6 +275,7 @@ class MeetingActor( //======================================= // internal messages case msg: MonitorNumberOfUsersInternalMsg => handleMonitorNumberOfUsers(msg) + case msg: MonitorGuestWaitPresenceInternalMsg => handleMonitorGuestWaitPresenceInternalMsg(msg) case msg: SetPresenterInDefaultPodInternalMsg => state = presentationPodsApp.handleSetPresenterInDefaultPodInternalMsg(msg, state, liveMeeting, msgBus) case msg: UserClosedAllGraphqlConnectionsInternalMsg => state = handleUserClosedAllGraphqlConnectionsInternalMsg(msg, state) @@ -280,15 +284,7 @@ class MeetingActor( state = handleUserEstablishedGraphqlConnectionInternalMsg(msg, state) updateModeratorsPresence() - case msg: ExtendMeetingDuration => handleExtendMeetingDuration(msg) - case msg: SendTimeRemainingAuditInternalMsg => - if (!liveMeeting.props.meetingProp.isBreakout) { - // Update users of meeting remaining time. - state = handleSendTimeRemainingUpdate(msg, state) - } - - // Update breakout rooms of remaining time - state = handleSendBreakoutTimeRemainingMsg(msg, state) + case msg: ExtendMeetingDuration => handleExtendMeetingDuration(msg) case msg: BreakoutRoomCreatedInternalMsg => state = handleBreakoutRoomCreatedInternalMsg(msg, state) case msg: SendBreakoutUsersAuditInternalMsg => handleSendBreakoutUsersUpdateInternalMsg(msg) case msg: BreakoutRoomUsersUpdateInternalMsg => state = handleBreakoutRoomUsersUpdateInternalMsg(msg, state) @@ -297,13 +293,9 @@ class MeetingActor( case msg: EjectUserFromBreakoutInternalMsg => handleEjectUserFromBreakoutInternalMsgHdlr(msg) case msg: BreakoutRoomEndedInternalMsg => state = handleBreakoutRoomEndedInternalMsg(msg, state) case msg: SendMessageToBreakoutRoomInternalMsg => state = handleSendMessageToBreakoutRoomInternalMsg(msg, state, liveMeeting, msgBus) - case msg: SendBreakoutTimeRemainingInternalMsg => - handleSendBreakoutTimeRemainingInternalMsg(msg) - case msg: CapturePresentationReqInternalMsg => presentationPodsApp.handle(msg, state, liveMeeting, msgBus) - case msg: SendRecordingTimerInternalMsg => - state = usersApp.handleSendRecordingTimerInternalMsg(msg, state) + case msg: CapturePresentationReqInternalMsg => presentationPodsApp.handle(msg, state, liveMeeting, msgBus) - case _ => // do nothing + case _ => // do nothing } private def initLockSettings(liveMeeting: LiveMeeting, lockSettingsProp: LockSettingsProps): Unit = { @@ -345,6 +337,21 @@ class MeetingActor( } } + private def initTimer(liveMeeting: LiveMeeting): Unit = { + val timerEnabled = getConfigPropertyValueByPathAsBooleanOrElse( + liveMeeting.clientSettings, + "public.timer.enabled", + alternativeValue = true + ) + + if (timerEnabled) { + val timerDefaultTimeInMinutes = getConfigPropertyValueByPathAsIntOrElse(liveMeeting.clientSettings, "public.timer.time", 5) + val timerDefaultTimeInMilli = timerDefaultTimeInMinutes * 60000 + TimerModel.createTimer(liveMeeting.timerModel, time = timerDefaultTimeInMilli) + TimerDAO.insert(liveMeeting.props.meetingProp.intId, liveMeeting.timerModel) + } + } + private def updateVoiceUserLastActivity(userId: String) { for { vu <- VoiceUsers.findWithVoiceUserId(liveMeeting.voiceUsers, userId) @@ -379,6 +386,20 @@ class MeetingActor( } } + private def endTimedOutBreakoutRooms(): Unit = { + for { + model <- state.breakout + startedOn <- model.startedOn + } yield { + val endMeetingTime = TimeUtil.millisToSeconds(startedOn) + model.durationInSeconds + val timeRemaining = endMeetingTime - TimeUtil.millisToSeconds(System.currentTimeMillis()) + + if (timeRemaining < 0) { + endAllBreakoutRooms(eventBus, liveMeeting, state, MeetingEndReason.BREAKOUT_ENDED_EXCEEDING_DURATION) + } + } + } + private def updateUserLastInactivityInspect(userId: String) { for { user <- Users2x.findWithIntId(liveMeeting.users2x, userId) @@ -398,21 +419,19 @@ class MeetingActor( private def handleMessageThatAffectsInactivity(msg: BbbCommonEnvCoreMsg): Unit = { msg.core match { - case m: EndMeetingSysCmdMsg => handleEndMeeting(m, state) + case m: EndMeetingSysCmdMsg => handleEndMeeting(m, state) // Users - case m: ValidateAuthTokenReqMsg => state = usersApp.handleValidateAuthTokenReqMsg(m, state) case m: UserJoinMeetingReqMsg => state = handleUserJoinMeetingReqMsg(m, state) updateModeratorsPresence() - case m: UserJoinMeetingAfterReconnectReqMsg => - state = handleUserJoinMeetingAfterReconnectReqMsg(m, state) - updateModeratorsPresence() case m: UserLeaveReqMsg => state = handleUserLeaveReqMsg(m, state) updateModeratorsPresence() - case m: UserJoinedVoiceConfEvtMsg => handleUserJoinedVoiceConfEvtMsg(m) + case m: UserJoinedVoiceConfEvtMsg => + handleUserJoinedVoiceConfEvtMsg(m) + updateVoiceUserLastActivity(m.body.voiceUserId) case m: LogoutAndEndMeetingCmdMsg => usersApp.handleLogoutAndEndMeetingCmdMsg(m, state) case m: SetRecordingStatusCmdMsg => state = usersApp.handleSetRecordingStatusCmdMsg(m, state) @@ -420,19 +439,28 @@ class MeetingActor( case m: RecordAndClearPreviousMarkersCmdMsg => state = usersApp.handleRecordAndClearPreviousMarkersCmdMsg(m, state) updateUserLastActivity(m.body.setBy) - case m: GetRecordingStatusReqMsg => usersApp.handleGetRecordingStatusReqMsg(m) - case m: ChangeUserEmojiCmdMsg => handleChangeUserEmojiCmdMsg(m) - case m: ChangeUserReactionEmojiReqMsg => usersApp.handleChangeUserReactionEmojiReqMsg(m) - case m: ChangeUserRaiseHandReqMsg => usersApp.handleChangeUserRaiseHandReqMsg(m) - case m: ChangeUserAwayReqMsg => usersApp.handleChangeUserAwayReqMsg(m) - case m: UserReactionTimeExpiredCmdMsg => handleUserReactionTimeExpiredCmdMsg(m) - case m: ClearAllUsersEmojiCmdMsg => handleClearAllUsersEmojiCmdMsg(m) - case m: ClearAllUsersReactionCmdMsg => handleClearAllUsersReactionCmdMsg(m) - case m: ChangeUserPinStateReqMsg => usersApp.handleChangeUserPinStateReqMsg(m) - case m: ChangeUserMobileFlagReqMsg => usersApp.handleChangeUserMobileFlagReqMsg(m) - case m: UserConnectionAliveReqMsg => usersApp.handleUserConnectionAliveReqMsg(m) - case m: SetUserSpeechLocaleReqMsg => usersApp.handleSetUserSpeechLocaleReqMsg(m) - case m: SetUserSpeechOptionsReqMsg => usersApp.handleSetUserSpeechOptionsReqMsg(m) + case m: ChangeUserReactionEmojiReqMsg => + usersApp.handleChangeUserReactionEmojiReqMsg(m) + updateUserLastActivity(m.header.userId) + case m: ChangeUserRaiseHandReqMsg => + usersApp.handleChangeUserRaiseHandReqMsg(m) + updateUserLastActivity(m.header.userId) + case m: ChangeUserAwayReqMsg => + usersApp.handleChangeUserAwayReqMsg(m) + updateUserLastActivity(m.header.userId) + case m: ClearAllUsersReactionCmdMsg => + handleClearAllUsersReactionCmdMsg(m) + updateUserLastActivity(m.header.userId) + case m: ChangeUserPinStateReqMsg => + usersApp.handleChangeUserPinStateReqMsg(m) + updateUserLastActivity(m.body.changedBy) + case m: UserConnectionAliveReqMsg => usersApp.handleUserConnectionAliveReqMsg(m) + case m: SetUserSpeechLocaleReqMsg => usersApp.handleSetUserSpeechLocaleReqMsg(m) + case m: SetUserSpeechOptionsReqMsg => usersApp.handleSetUserSpeechOptionsReqMsg(m) + case m: GetRecordingStatusReqMsg => usersApp.handleGetRecordingStatusReqMsg(m) + case m: SetUserCaptionLocaleReqMsg => usersApp.handleSetUserCaptionLocaleReqMsg(m) + case m: SetUserClientSettingsReqMsg => usersApp.handleSetUserClientSettingsReqMsg(m) + case m: SetUserEchoTestRunningReqMsg => usersApp.handleSetUserEchoTestRunningReqMsg(m) // Client requested to eject user case m: EjectUserFromMeetingCmdMsg => @@ -441,19 +469,28 @@ class MeetingActor( // Another part of system (e.g. bbb-apps) requested to eject user. case m: EjectUserFromMeetingSysMsg => usersApp.handleEjectUserFromMeetingSysMsg(m) - case m: GetUsersMeetingReqMsg => usersApp.handleGetUsersMeetingReqMsg(m) case m: ChangeUserRoleCmdMsg => usersApp.handleChangeUserRoleCmdMsg(m) updateUserLastActivity(m.body.changedBy) updateModeratorsPresence() // Whiteboard - case m: SendCursorPositionPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: ClearWhiteboardPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: DeleteWhiteboardAnnotationsPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: ModifyWhiteboardAccessPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: SendWhiteboardAnnotationsPubMsg => wbApp.handle(m, liveMeeting, msgBus) - case m: GetWhiteboardAnnotationsReqMsg => wbApp.handle(m, liveMeeting, msgBus) + case m: SendCursorPositionPubMsg => + wbApp.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: ClearWhiteboardPubMsg => + wbApp.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: DeleteWhiteboardAnnotationsPubMsg => + wbApp.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: ModifyWhiteboardAccessPubMsg => + wbApp.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: SendWhiteboardAnnotationsPubMsg => + wbApp.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: GetWhiteboardAnnotationsReqMsg => wbApp.handle(m, liveMeeting, msgBus) // Poll case m: StartPollReqMsg => @@ -477,18 +514,19 @@ class MeetingActor( updateUserLastActivity(m.body.requesterId) // Breakout - case m: BreakoutRoomsListMsg => state = handleBreakoutRoomsListMsg(m, state) - case m: CreateBreakoutRoomsCmdMsg => state = handleCreateBreakoutRoomsCmdMsg(m, state) - case m: EndAllBreakoutRoomsMsg => state = handleEndAllBreakoutRoomsMsg(m, state) - case m: RequestBreakoutJoinURLReqMsg => state = handleRequestBreakoutJoinURLReqMsg(m, state) - case m: TransferUserToMeetingRequestMsg => state = handleTransferUserToMeetingRequestMsg(m, state) - case m: UpdateBreakoutRoomsTimeReqMsg => state = handleUpdateBreakoutRoomsTimeMsg(m, state) - case m: SendMessageToAllBreakoutRoomsReqMsg => state = handleSendMessageToAllBreakoutRoomsMsg(m, state) - case m: ChangeUserBreakoutReqMsg => state = handleChangeUserBreakoutReqMsg(m, state) + case m: BreakoutRoomsListMsg => state = handleBreakoutRoomsListMsg(m, state) + case m: CreateBreakoutRoomsCmdMsg => state = handleCreateBreakoutRoomsCmdMsg(m, state) + case m: EndAllBreakoutRoomsMsg => state = handleEndAllBreakoutRoomsMsg(m, state) + case m: RequestBreakoutJoinURLReqMsg => state = handleRequestBreakoutJoinURLReqMsg(m, state) + case m: SetBreakoutRoomInviteDismissedReqMsg => handleSetBreakoutRoomInviteDismissedReqMsg(m) + case m: TransferUserToMeetingRequestMsg => state = handleTransferUserToMeetingRequestMsg(m, state) + case m: UpdateBreakoutRoomsTimeReqMsg => state = handleUpdateBreakoutRoomsTimeMsg(m, state) + case m: SendMessageToAllBreakoutRoomsReqMsg => state = handleSendMessageToAllBreakoutRoomsMsg(m, state) + case m: ChangeUserBreakoutReqMsg => state = handleChangeUserBreakoutReqMsg(m, state) // Voice - case m: UserLeftVoiceConfEvtMsg => handleUserLeftVoiceConfEvtMsg(m) - case m: UserMutedInVoiceConfEvtMsg => handleUserMutedInVoiceConfEvtMsg(m) + case m: UserLeftVoiceConfEvtMsg => handleUserLeftVoiceConfEvtMsg(m) + case m: UserMutedInVoiceConfEvtMsg => handleUserMutedInVoiceConfEvtMsg(m) case m: UserTalkingInVoiceConfEvtMsg => updateVoiceUserLastActivity(m.body.voiceUserId) handleUserTalkingInVoiceConfEvtMsg(m) @@ -529,42 +567,59 @@ class MeetingActor( case m: BroadcastPushLayoutMsg => handleBroadcastPushLayoutMsg(m) // Pads - case m: PadCreateGroupReqMsg => padsApp2x.handle(m, liveMeeting, msgBus) case m: PadGroupCreatedEvtMsg => padsApp2x.handle(m, liveMeeting, msgBus) case m: PadCreateReqMsg => padsApp2x.handle(m, liveMeeting, msgBus) case m: PadCreatedEvtMsg => padsApp2x.handle(m, liveMeeting, msgBus) case m: PadCreateSessionReqMsg => padsApp2x.handle(m, liveMeeting, msgBus) case m: PadSessionCreatedEvtMsg => padsApp2x.handle(m, liveMeeting, msgBus) case m: PadSessionDeletedSysMsg => padsApp2x.handle(m, liveMeeting, msgBus) - case m: PadUpdatedSysMsg => padsApp2x.handle(m, liveMeeting, msgBus) - case m: PadContentSysMsg => padsApp2x.handle(m, liveMeeting, msgBus) - case m: PadPatchSysMsg => padsApp2x.handle(m, liveMeeting, msgBus) - case m: PadUpdatePubMsg => padsApp2x.handle(m, liveMeeting, msgBus) - case m: PadPinnedReqMsg => padsApp2x.handle(m, liveMeeting, msgBus) + case m: PadUpdatedSysMsg => + padsApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.body.userId) + case m: PadContentSysMsg => padsApp2x.handle(m, liveMeeting, msgBus) + case m: PadPatchSysMsg => padsApp2x.handle(m, liveMeeting, msgBus) + case m: PadUpdatePubMsg => padsApp2x.handle(m, liveMeeting, msgBus) + case m: PadPinnedReqMsg => + padsApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) // Lock Settings case m: ChangeLockSettingsInMeetingCmdMsg => handleSetLockSettings(m) updateUserLastActivity(m.body.setBy) - case m: LockUserInMeetingCmdMsg => handleLockUserInMeetingCmdMsg(m) - case m: LockUsersInMeetingCmdMsg => handleLockUsersInMeetingCmdMsg(m) - case m: GetLockSettingsReqMsg => handleGetLockSettingsReqMsg(m) + case m: LockUserInMeetingCmdMsg => + handleLockUserInMeetingCmdMsg(m) + updateUserLastActivity(m.body.lockedBy) + case m: LockUsersInMeetingCmdMsg => + handleLockUsersInMeetingCmdMsg(m) + updateUserLastActivity(m.body.lockedBy) // Presentation - case m: PreuploadedPresentationsSysPubMsg => presentationApp2x.handle(m, liveMeeting, msgBus) - case m: AssignPresenterReqMsg => state = handlePresenterChange(m, state) - case m: MakePresentationDownloadReqMsg => presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: NewPresFileAvailableMsg => presentationPodsApp.handle(m, liveMeeting, msgBus) - case m: PresAnnStatusMsg => presentationPodsApp.handle(m, liveMeeting, msgBus) + case m: PreuploadedPresentationsSysPubMsg => presentationApp2x.handle(m, liveMeeting, msgBus) + case m: AssignPresenterReqMsg => + state = handlePresenterChange(m, state) + updateUserLastActivity(m.body.assignedBy) + case m: MakePresentationDownloadReqMsg => + presentationPodsApp.handle(m, state, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: NewPresFileAvailableMsg => presentationPodsApp.handle(m, liveMeeting, msgBus) + case m: PresAnnStatusMsg => presentationPodsApp.handle(m, liveMeeting, msgBus) // Presentation Pods - case m: CreateNewPresentationPodPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: RemovePresentationPodPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: GetAllPresentationPodsReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: SetCurrentPresentationPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: PresentationConversionCompletedSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: PdfConversionInvalidErrorSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: SetCurrentPagePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: CreateNewPresentationPodPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: RemovePresentationPodPubMsg => + state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: GetAllPresentationPodsReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: SetCurrentPresentationPubMsg => + state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: PresentationConversionCompletedSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: PdfConversionInvalidErrorSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: SetCurrentPagePubMsg => + state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: SetPageInfiniteWhiteboardPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) case m: RemovePresentationPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) case m: SetPresentationDownloadablePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) case m: PresentationConversionUpdateSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) @@ -574,37 +629,51 @@ class MeetingActor( case m: PresentationPageGeneratedSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) case m: PresentationPageCountErrorSysPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) case m: PresentationUploadTokenReqMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: ResizeAndMovePagePubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: SlideResizedPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: PresentationPageConvertedSysMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: PresentationPageConversionStartedSysMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) - case m: PresentationConversionEndedSysMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: ResizeAndMovePagePubMsg => + state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: SlideResizedPubMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: PresentationPageConvertedSysMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: PresentationPageConversionStartedSysMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) + case m: PresentationConversionEndedSysMsg => state = presentationPodsApp.handle(m, state, liveMeeting, msgBus) // Caption - case m: EditCaptionHistoryPubMsg => captionApp2x.handle(m, liveMeeting, msgBus) - case m: UpdateCaptionOwnerPubMsg => captionApp2x.handle(m, liveMeeting, msgBus) - case m: SendCaptionHistoryReqMsg => captionApp2x.handle(m, liveMeeting, msgBus) + case m: EditCaptionHistoryPubMsg => captionApp2x.handle(m, liveMeeting, msgBus) + case m: AddCaptionLocalePubMsg => captionApp2x.handle(m, liveMeeting, msgBus) + case m: SendCaptionHistoryReqMsg => captionApp2x.handle(m, liveMeeting, msgBus) + case m: CaptionSubmitTranscriptPubMsg => captionApp2x.handle(m, liveMeeting, msgBus) // Guests - case m: GetGuestsWaitingApprovalReqMsg => handleGetGuestsWaitingApprovalReqMsg(m) - case m: SetGuestPolicyCmdMsg => handleSetGuestPolicyMsg(m) - case m: SetGuestLobbyMessageCmdMsg => handleSetGuestLobbyMessageMsg(m) - case m: GuestsWaitingApprovedMsg => handleGuestsWaitingApprovedMsg(m) - case m: GuestWaitingLeftMsg => handleGuestWaitingLeftMsg(m) - case m: GetGuestPolicyReqMsg => handleGetGuestPolicyReqMsg(m) - case m: UpdatePositionInWaitingQueueReqMsg => handleUpdatePositionInWaitingQueueReqMsg(m) - case m: SetPrivateGuestLobbyMessageCmdMsg => handleSetPrivateGuestLobbyMessageCmdMsg(m) + case m: GetGuestsWaitingApprovalReqMsg => handleGetGuestsWaitingApprovalReqMsg(m) + case m: SetGuestPolicyCmdMsg => + handleSetGuestPolicyMsg(m) + updateUserLastActivity(m.header.userId) + case m: SetGuestLobbyMessageCmdMsg => + handleSetGuestLobbyMessageMsg(m) + updateUserLastActivity(m.header.userId) + case m: GuestsWaitingApprovedMsg => + handleGuestsWaitingApprovedMsg(m) + updateUserLastActivity(m.header.userId) + case m: GetGuestPolicyReqMsg => handleGetGuestPolicyReqMsg(m) + case m: UpdatePositionInWaitingQueueReqMsg => handleUpdatePositionInWaitingQueueReqMsg(m) + case m: SetPrivateGuestLobbyMessageCmdMsg => + handleSetPrivateGuestLobbyMessageCmdMsg(m) + updateUserLastActivity(m.header.userId) // Chat - case m: GetChatHistoryReqMsg => chatApp2x.handle(m, liveMeeting, msgBus) + case m: GetChatHistoryReqMsg => chatApp2x.handle(m, liveMeeting, msgBus) case m: SendPublicMessagePubMsg => chatApp2x.handle(m, liveMeeting, msgBus) updateUserLastActivity(m.body.message.fromUserId) case m: SendPrivateMessagePubMsg => chatApp2x.handle(m, liveMeeting, msgBus) updateUserLastActivity(m.body.message.fromUserId) - case m: ClearPublicChatHistoryPubMsg => state = chatApp2x.handle(m, state, liveMeeting, msgBus) - case m: UserTypingPubMsg => chatApp2x.handle(m, liveMeeting, msgBus) + case m: ClearPublicChatHistoryPubMsg => + state = chatApp2x.handle(m, state, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: UserTypingPubMsg => + chatApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) // Screenshare case m: ScreenshareRtmpBroadcastStartedVoiceConfEvtMsg => screenshareApp2x.handle(m, liveMeeting, msgBus) @@ -614,58 +683,87 @@ class MeetingActor( case m: GetScreenSubscribePermissionReqMsg => handleGetScreenSubscribePermissionReqMsg(m) // AudioCaptions - case m: UpdateTranscriptPubMsg => audioCaptionsApp2x.handle(m, liveMeeting, msgBus) - case m: TranscriptionProviderErrorMsg => audioCaptionsApp2x.handleTranscriptionProviderErrorMsg(m, liveMeeting, msgBus) + case m: UpdateTranscriptPubMsg => + audioCaptionsApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: TranscriptionProviderErrorMsg => audioCaptionsApp2x.handleTranscriptionProviderErrorMsg(m, liveMeeting, msgBus) // GroupChat case m: CreateGroupChatReqMsg => state = groupChatApp.handle(m, state, liveMeeting, msgBus) updateUserLastActivity(m.header.userId) - case m: GetGroupChatMsgsReqMsg => state = groupChatApp.handle(m, state, liveMeeting, msgBus) - case m: GetGroupChatsReqMsg => state = groupChatApp.handle(m, state, liveMeeting, msgBus) + case m: SetGroupChatLastSeenReqMsg => groupChatApp.handle(m, liveMeeting) + case m: SetGroupChatVisibleReqMsg => groupChatApp.handle(m, liveMeeting) + case m: GetGroupChatMsgsReqMsg => state = groupChatApp.handle(m, state, liveMeeting, msgBus) + case m: GetGroupChatsReqMsg => state = groupChatApp.handle(m, state, liveMeeting, msgBus) case m: SendGroupChatMessageMsg => state = groupChatApp.handle(m, state, liveMeeting, msgBus) updateUserLastActivity(m.body.msg.sender.id) + case m: SendGroupChatMessageFromApiSysPubMsg => + state = groupChatApp.handle(m, state, liveMeeting, msgBus) // Plugin - case m: PluginDataChannelPushEntryMsg => pluginHdlrs.handle(m, state, liveMeeting) - case m: PluginDataChannelDeleteEntryMsg => pluginHdlrs.handle(m, state, liveMeeting) - case m: PluginDataChannelResetMsg => pluginHdlrs.handle(m, state, liveMeeting) + case m: PluginDataChannelPushEntryMsg => pluginHdlrs.handle(m, state, liveMeeting) + case m: PluginDataChannelReplaceEntryMsg => pluginHdlrs.handle(m, state, liveMeeting) + case m: PluginDataChannelDeleteEntryMsg => pluginHdlrs.handle(m, state, liveMeeting) + case m: PluginDataChannelResetMsg => pluginHdlrs.handle(m, state, liveMeeting) // Webcams - case m: UserBroadcastCamStartMsg => webcamApp2x.handle(m, liveMeeting, msgBus) - case m: UserBroadcastCamStopMsg => webcamApp2x.handle(m, liveMeeting, msgBus) - case m: GetCamBroadcastPermissionReqMsg => webcamApp2x.handle(m, liveMeeting, msgBus) - case m: GetCamSubscribePermissionReqMsg => webcamApp2x.handle(m, liveMeeting, msgBus) - case m: CamStreamSubscribedInSfuEvtMsg => webcamApp2x.handle(m, liveMeeting, msgBus) - case m: CamStreamUnsubscribedInSfuEvtMsg => webcamApp2x.handle(m, liveMeeting, msgBus) - case m: CamBroadcastStoppedInSfuEvtMsg => webcamApp2x.handle(m, liveMeeting, msgBus) - case m: EjectUserCamerasCmdMsg => webcamApp2x.handle(m, liveMeeting, msgBus) - case m: GetWebcamsOnlyForModeratorReqMsg => webcamApp2x.handle(m, liveMeeting, msgBus) - case m: UpdateWebcamsOnlyForModeratorCmdMsg => webcamApp2x.handle(m, liveMeeting, msgBus) + case m: UserBroadcastCamStartMsg => + webcamApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: UserBroadcastCamStopMsg => + webcamApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: GetCamBroadcastPermissionReqMsg => webcamApp2x.handle(m, liveMeeting, msgBus) + case m: GetCamSubscribePermissionReqMsg => webcamApp2x.handle(m, liveMeeting, msgBus) + case m: CamStreamSubscribedInSfuEvtMsg => webcamApp2x.handle(m, liveMeeting, msgBus) + case m: CamStreamUnsubscribedInSfuEvtMsg => webcamApp2x.handle(m, liveMeeting, msgBus) + case m: CamBroadcastStoppedInSfuEvtMsg => webcamApp2x.handle(m, liveMeeting, msgBus) + case m: EjectUserCamerasCmdMsg => webcamApp2x.handle(m, liveMeeting, msgBus) + case m: GetWebcamsOnlyForModeratorReqMsg => webcamApp2x.handle(m, liveMeeting, msgBus) + case m: UpdateWebcamsOnlyForModeratorCmdMsg => + webcamApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.body.setBy) // ExternalVideo - case m: StartExternalVideoPubMsg => externalVideoApp2x.handle(m, liveMeeting, msgBus) - case m: UpdateExternalVideoPubMsg => externalVideoApp2x.handle(m, liveMeeting, msgBus) - case m: StopExternalVideoPubMsg => externalVideoApp2x.handle(m, liveMeeting, msgBus) + case m: StartExternalVideoPubMsg => + externalVideoApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: UpdateExternalVideoPubMsg => externalVideoApp2x.handle(m, liveMeeting, msgBus) + case m: StopExternalVideoPubMsg => + externalVideoApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) //Timer - case m: CreateTimerPubMsg => timerApp2x.handle(m, liveMeeting, msgBus) - case m: ActivateTimerReqMsg => timerApp2x.handle(m, liveMeeting, msgBus) - case m: DeactivateTimerReqMsg => timerApp2x.handle(m, liveMeeting, msgBus) - case m: StartTimerReqMsg => timerApp2x.handle(m, liveMeeting, msgBus) - case m: StopTimerReqMsg => timerApp2x.handle(m, liveMeeting, msgBus) - case m: SwitchTimerReqMsg => timerApp2x.handle(m, liveMeeting, msgBus) - case m: SetTimerReqMsg => timerApp2x.handle(m, liveMeeting, msgBus) - case m: ResetTimerReqMsg => timerApp2x.handle(m, liveMeeting, msgBus) - case m: SetTrackReqMsg => timerApp2x.handle(m, liveMeeting, msgBus) - case m: TimerEndedPubMsg => timerApp2x.handle(m, liveMeeting, msgBus) + case m: ActivateTimerReqMsg => + timerApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: DeactivateTimerReqMsg => + timerApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: StartTimerReqMsg => + timerApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: StopTimerReqMsg => + timerApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: SwitchTimerReqMsg => + timerApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: SetTimerReqMsg => + timerApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: ResetTimerReqMsg => + timerApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) + case m: SetTrackReqMsg => + timerApp2x.handle(m, liveMeeting, msgBus) + updateUserLastActivity(m.header.userId) - case m: ValidateConnAuthTokenSysMsg => handleValidateConnAuthTokenSysMsg(m) + case m: UserActivitySignCmdMsg => handleUserActivitySignCmdMsg(m) - case m: UserActivitySignCmdMsg => handleUserActivitySignCmdMsg(m) - - case _ => log.warning("***** Cannot handle " + msg.envelope.name) + case _ => log.warning("***** Cannot handle " + msg.envelope.name) } } @@ -681,6 +779,33 @@ class MeetingActor( outGW.send(event2) } + private def handleMeetingTasksExecutor(): Unit = { + clearExpiredReactionEmojis() + stopFinishedTimer() + endTimedOutBreakoutRooms() + } + + private def clearExpiredReactionEmojis(): Unit = { + val userReactionExpire = getConfigPropertyValueByPathAsIntOrElse(liveMeeting.clientSettings, "public.userReaction.expire", 30) + val now = System.currentTimeMillis() + + for { + user <- Users2x.findAll(liveMeeting.users2x) + } yield { + if (user.reactionEmoji != null && user.reactionEmoji != "none") { + if (now - user.reactionChangedOn > userReactionExpire * 1000) { + Users2x.setReactionEmoji(liveMeeting.users2x, user.intId, "none", 0) + } + } + } + } + + private def stopFinishedTimer(): Unit = { + if (TimerModel.resetTimerIfFinished(liveMeeting.timerModel)) { + TimerDAO.update(liveMeeting.props.meetingProp.intId, liveMeeting.timerModel) + } + } + private def prepareMeetingInfo(): MeetingInfoAnalytics = { val meetingName: String = liveMeeting.props.meetingProp.name val externalId: String = liveMeeting.props.meetingProp.extId @@ -755,41 +880,6 @@ class MeetingActor( PresentationInfo(presentationId, presentationName) } - def handleGetRunningMeetingStateReqMsg(msg: GetRunningMeetingStateReqMsg): Unit = { - processGetRunningMeetingStateReqMsg() - } - - def processGetRunningMeetingStateReqMsg(): Unit = { - - // sync all meetings - handleSyncGetMeetingInfoRespMsg(liveMeeting.props) - - // sync all users - usersApp.handleSyncGetUsersMeetingRespMsg() - - // sync all presentations - presentationPodsApp.handleSyncGetPresentationPods(state, liveMeeting, msgBus) - - // sync all group chats and group chat messages - groupChatApp.handleSyncGetGroupChatsInfo(state, liveMeeting, msgBus) - - // sync all voice users - handleSyncGetVoiceUsersMsg(state, liveMeeting, msgBus) - - // sync all lock settings - handleSyncGetLockSettingsMsg(state, liveMeeting, msgBus) - - // send all screen sharing info - screenshareApp2x.handleSyncGetScreenshareInfoRespMsg(liveMeeting, msgBus) - - // send all webcam info - webcamApp2x.handleSyncGetWebcamInfoRespMsg(liveMeeting, msgBus) - } - - def handleGetAllMeetingsReqMsg(msg: GetAllMeetingsReqMsg): Unit = { - processGetRunningMeetingStateReqMsg() - } - def handlePresenterChange(msg: AssignPresenterReqMsg, state: MeetingState2x): MeetingState2x = { // Stop poll if one is running as presenter left pollApp.stopPoll(state, msg.header.userId, liveMeeting, msgBus) @@ -820,6 +910,26 @@ class MeetingActor( checkIfNeedToEndMeetingWhenNoModerators(liveMeeting) } + def handleMonitorGuestWaitPresenceInternalMsg(msg: MonitorGuestWaitPresenceInternalMsg) { + if (liveMeeting.props.usersProp.waitingGuestUsersTimeout > 0) { + for { + regUser <- RegisteredUsers.findAll(liveMeeting.registeredUsers) + } yield { + if (!regUser.loggedOut + && !regUser.ejected + && regUser.guestStatus == GuestStatus.WAIT + && !regUser.graphqlConnected + && regUser.graphqlDisconnectedOn != 0) { + val diff = System.currentTimeMillis() - regUser.graphqlDisconnectedOn + if (diff > liveMeeting.props.usersProp.waitingGuestUsersTimeout) { + GuestsWaiting.remove(liveMeeting.guestsWaiting, regUser.id) + UsersApp.guestWaitingLeft(liveMeeting, regUser.id, outGW) + } + } + } + } + } + def checkVoiceConfUsersStatus(): Unit = { val event = MsgBuilder.buildLastcheckVoiceConfUsersStatus( props.meetingProp.intId, @@ -934,8 +1044,6 @@ class MeetingActor( RegisteredUsers.updateUserJoin(liveMeeting.registeredUsers, ru, joined = false) - captionApp2x.handleUserLeavingMsg(leftUser.intId, liveMeeting, msgBus) - // send a user left event for the clients to update val userLeftMeetingEvent = MsgBuilder.buildUserLeftMeetingEvtMsg(liveMeeting.props.meetingProp.intId, u.intId) outGW.send(userLeftMeetingEvent) @@ -1037,8 +1145,6 @@ class MeetingActor( ban = false ) - Sender.sendDisconnectClientSysMsg(liveMeeting.props.meetingProp.intId, u.intId, SystemUser.ID, EjectReasonCode.USER_INACTIVITY, outGW) - // Force reconnection with graphql to refresh permissions for { regUser <- RegisteredUsers.findWithUserId(u.intId, liveMeeting.registeredUsers) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActorAudit.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActorAudit.scala index 4b6d6a78b1..6884d53580 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActorAudit.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActorAudit.scala @@ -71,9 +71,7 @@ class MeetingActorAudit( def handleMonitorNumberOfWebUsers() { eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, MonitorNumberOfUsersInternalMsg(props.meetingProp.intId))) - - // Trigger updating users of time remaining on meeting. - eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendTimeRemainingAuditInternalMsg(props.meetingProp.intId, 0))) + eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, MonitorGuestWaitPresenceInternalMsg(props.meetingProp.intId))) if (props.meetingProp.isBreakout) { // This is a breakout room. Update the main meeting with list of users in this breakout room. @@ -82,11 +80,6 @@ class MeetingActorAudit( SendBreakoutUsersAuditInternalMsg(props.breakoutProps.parentId, props.meetingProp.intId) )) } - - // Trigger recording timer, only for meeting allowing recording - if (props.recordProp.record) { - eventBus.publish(BigBlueButtonEvent(props.meetingProp.intId, SendRecordingTimerInternalMsg(props.meetingProp.intId))) - } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/HtmlUtil.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/HtmlUtil.scala new file mode 100644 index 0000000000..086e3143a3 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/HtmlUtil.scala @@ -0,0 +1,29 @@ +package org.bigbluebutton.core.util + +object HtmlUtil { + private val HTML_SAFE_MAP: Map[Char, String] = Map( + '<' -> "<", + '>' -> ">", + '"' -> """, + '\'' -> "'" + ) + + private val RegexWebUrl = """(?i)\b((?:https?|ftp)://[^\s/$.?#].[^\s]*)\b""".r + + def htmlToHtmlEntities(message: String): String = { + var parsedMessage = Option(message).getOrElse("").trim + + // Replace
with \n\r + parsedMessage = parsedMessage.replaceAll("(?i)", "\n\r") + + // Escape HTML characters + parsedMessage = HTML_SAFE_MAP.foldLeft(parsedMessage) { case (msg, (char, safe)) => + msg.replace(char.toString, safe) + } + + // Replace flash links to flash valid ones + parsedMessage = RegexWebUrl.replaceAllIn(parsedMessage, m => s"${m.matched}") + + parsedMessage + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala index 3a6e542498..c8a3fdd6f9 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala @@ -35,18 +35,12 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = { msg.core match { - case m: GetAllMeetingsReqMsg => logMessage(msg) - case m: GetRunningMeetingsRespMsg => logMessage(msg) - case m: GetRunningMeetingsReqMsg => logMessage(msg) - case m: RegisterUserReqMsg => logMessage(msg) case m: UserRegisteredRespMsg => logMessage(msg) case m: DisconnectAllClientsSysMsg => logMessage(msg) - case m: DisconnectClientSysMsg => logMessage(msg) case m: MeetingEndingEvtMsg => logMessage(msg) case m: MeetingCreatedEvtMsg => logMessage(msg) case m: LogoutAndEndMeetingCmdMsg => logMessage(msg) - case m: ValidateAuthTokenRespMsg => logMessage(msg) case m: UserJoinedMeetingEvtMsg => logMessage(msg) case m: RecordingStatusChangedEvtMsg => logMessage(msg) case m: WebcamsOnlyForModeratorChangedEvtMsg => logMessage(msg) @@ -56,6 +50,7 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { case m: EjectUserFromVoiceConfSysMsg => logMessage(msg) case m: CreateBreakoutRoomSysCmdMsg => logMessage(msg) case m: RequestBreakoutJoinURLReqMsg => logMessage(msg) + case m: SetBreakoutRoomInviteDismissedReqMsg => logMessage(msg) case m: EndAllBreakoutRoomsMsg => logMessage(msg) case m: TransferUserToMeetingRequestMsg => logMessage(msg) case m: UpdateBreakoutRoomsTimeReqMsg => logMessage(msg) @@ -77,7 +72,6 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { case m: UserDisconnectedFromGlobalAudioMsg => logMessage(msg) case m: AssignPresenterReqMsg => logMessage(msg) case m: ChangeUserPinStateReqMsg => logMessage(msg) - case m: ChangeUserMobileFlagReqMsg => logMessage(msg) case m: UserConnectionAliveReqMsg => logMessage(msg) case m: ScreenshareRtmpBroadcastStartedVoiceConfEvtMsg => logMessage(msg) case m: ScreenshareRtmpBroadcastStoppedVoiceConfEvtMsg => logMessage(msg) @@ -85,7 +79,6 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { case m: ScreenshareRtmpBroadcastStoppedEvtMsg => logMessage(msg) case m: StartRecordingVoiceConfSysMsg => logMessage(msg) case m: StopRecordingVoiceConfSysMsg => logMessage(msg) - //case m: UpdateRecordingTimerEvtMsg => logMessage(msg) case m: RecordAndClearPreviousMarkersCmdMsg => logMessage(msg) case m: TransferUserToVoiceConfSysMsg => logMessage(msg) case m: UserBroadcastCamStartMsg => logMessage(msg) @@ -107,6 +100,7 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { case m: ChannelHoldChangedVoiceConfEvtMsg => logMessage(msg) case m: ToggleListenOnlyModeSysMsg => logMessage(msg) case m: ListenOnlyModeToggledInSfuEvtMsg => logMessage(msg) + case m: MeetingMutedEvtMsg => logMessage(msg) // Breakout case m: BreakoutRoomEndedEvtMsg => logMessage(msg) @@ -145,6 +139,8 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { case m: GetGroupChatMsgsReqMsg => logChatMessage(msg) case m: GetGroupChatMsgsRespMsg => logChatMessage(msg) case m: CreateGroupChatReqMsg => logChatMessage(msg) + case m: SetGroupChatLastSeenReqMsg => logChatMessage(msg) + case m: SetGroupChatVisibleReqMsg => logChatMessage(msg) case m: GroupChatCreatedEvtMsg => logChatMessage(msg) case m: GetGroupChatsReqMsg => logChatMessage(msg) case m: GetGroupChatsRespMsg => logChatMessage(msg) @@ -152,7 +148,6 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { // Guest Management case m: GuestsWaitingApprovedMsg => logMessage(msg) case m: GuestsWaitingApprovedEvtMsg => logMessage(msg) - case m: GuestWaitingLeftMsg => logMessage(msg) case m: GuestWaitingLeftEvtMsg => logMessage(msg) case m: GuestsWaitingForApprovalEvtMsg => logMessage(msg) case m: UpdatePositionInWaitingQueueReqMsg => logMessage(msg) @@ -167,8 +162,6 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { // System case m: ClientToServerLatencyTracerMsg => traceMessage(msg) case m: ServerToClientLatencyTracerMsg => traceMessage(msg) - case m: ValidateConnAuthTokenSysMsg => traceMessage(msg) - case m: ValidateConnAuthTokenSysRespMsg => traceMessage(msg) // Recording case m: RecordingChapterBreakSysMsg => logMessage(msg) @@ -179,7 +172,6 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { case m: GetLockSettingsRespMsg => logMessage(msg) case m: ChangeLockSettingsInMeetingCmdMsg => logMessage(msg) - case m: GetLockSettingsReqMsg => logMessage(msg) case m: LockSettingsNotInitializedRespMsg => logMessage(msg) case m: MeetingInfoAnalyticsMsg => logMessage(msg) @@ -188,7 +180,6 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging { case m: BroadcastLayoutEvtMsg => logMessage(msg) // Pads - case m: PadCreateGroupReqMsg => logMessage(msg) case m: PadCreateGroupCmdMsg => logMessage(msg) case m: PadGroupCreatedEvtMsg => logMessage(msg) case m: PadGroupCreatedRespMsg => logMessage(msg) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala index 123b8b8152..051dad9a8e 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/FromAkkaAppsMsgSenderActor.scala @@ -23,14 +23,6 @@ class FromAkkaAppsMsgSenderActor(msgSender: MessageSender) msg.envelope.name match { - // HTML5 sync messages - case SyncGetPresentationPodsRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json) - case SyncGetMeetingInfoRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json) - case SyncGetUsersMeetingRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json) - case SyncGetGroupChatsRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json) - case SyncGetGroupChatMsgsRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json) - case SyncGetVoiceUsersRespMsg.NAME => msgSender.send(toHTML5RedisChannel, json) - // Sent to FreeSWITCH case EjectAllFromVoiceConfMsg.NAME => msgSender.send(toVoiceConfRedisChannel, json) @@ -96,6 +88,8 @@ class FromAkkaAppsMsgSenderActor(msgSender: MessageSender) msgSender.send(fromAkkaAppsPresRedisChannel, json) case SetCurrentPageEvtMsg.NAME => msgSender.send(fromAkkaAppsPresRedisChannel, json) + case SetPageInfiniteWhiteboardEvtMsg.NAME => + msgSender.send(fromAkkaAppsPresRedisChannel, json) case ResizeAndMovePageEvtMsg.NAME => msgSender.send(fromAkkaAppsPresRedisChannel, json) case RemovePresentationEvtMsg.NAME => @@ -104,16 +98,10 @@ class FromAkkaAppsMsgSenderActor(msgSender: MessageSender) msgSender.send(fromAkkaAppsPresRedisChannel, json) // Breakout - case UpdateBreakoutUsersEvtMsg.NAME => - msgSender.send(fromAkkaAppsPresRedisChannel, json) case BreakoutRoomsListEvtMsg.NAME => msgSender.send(fromAkkaAppsPresRedisChannel, json) - case BreakoutRoomsTimeRemainingUpdateEvtMsg.NAME => - msgSender.send(fromAkkaAppsPresRedisChannel, json) case BreakoutRoomStartedEvtMsg.NAME => msgSender.send(fromAkkaAppsPresRedisChannel, json) - case MeetingTimeRemainingUpdateEvtMsg.NAME => - msgSender.send(fromAkkaAppsPresRedisChannel, json) //================================================================== //================================================================== @@ -123,10 +111,6 @@ class FromAkkaAppsMsgSenderActor(msgSender: MessageSender) case UserRespondedToPollRecordMsg.NAME => //================================================================== - case ValidateAuthTokenRespMsg.NAME => - msgSender.send(fromAkkaAppsRedisChannel, json) // needed for cases when single nodejs process is running (like in development) - msgSender.send("from-akka-apps-frontend-redis-channel", json) - // Message duplicated for frontend and backend processes case MeetingCreatedEvtMsg.NAME => msgSender.send(fromAkkaAppsRedisChannel, json) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala index 8b59f47e63..03ff76edea 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala @@ -37,6 +37,7 @@ object MeetingStatus2x { def getMeetingExtensionProp(status: MeetingStatus2x): MeetingExtensionProp = status.extension def muteMeeting(status: MeetingStatus2x) = status.meetingMuted = true def unmuteMeeting(status: MeetingStatus2x) = status.meetingMuted = false + def setMeetingMuted(status: MeetingStatus2x, value: Boolean) = status.meetingMuted = value def isMeetingMuted(status: MeetingStatus2x): Boolean = status.meetingMuted def recordingStarted(status: MeetingStatus2x) = status.recording = true def recordingStopped(status: MeetingStatus2x) = status.recording = false diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteAllExceptPresentersCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteAllExceptPresentersCmdMsgHdlr.scala index 79a25310ca..95652eb428 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteAllExceptPresentersCmdMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteAllExceptPresentersCmdMsgHdlr.scala @@ -7,6 +7,7 @@ import org.bigbluebutton.core2.MeetingStatus2x import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } import org.bigbluebutton.core.db.NotificationDAO import org.bigbluebutton.core2.message.senders.MsgBuilder +import org.bigbluebutton.core.apps.voice.VoiceApp trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait { this: MeetingActor => @@ -49,7 +50,7 @@ trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait { } val muted = MeetingStatus2x.isMeetingMuted(liveMeeting.status) - val event = build(props.meetingProp.intId, msg.body.mutedBy, muted, msg.body.mutedBy) + val event = MsgBuilder.buildMeetingMutedEvtMsg(props.meetingProp.intId, msg.body.mutedBy, muted, msg.body.mutedBy) outGW.send(event) @@ -60,8 +61,8 @@ trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait { VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu => if (!vu.listenOnly) { Users2x.findWithIntId(liveMeeting.users2x, vu.intId) match { - case Some(u) => if (!u.presenter) muteUserInVoiceConf(vu, muted) - case None => muteUserInVoiceConf(vu, muted) + case Some(u) => if (!u.presenter) VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, muted) + case None => VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, muted) } } } @@ -74,28 +75,4 @@ trait MuteAllExceptPresentersCmdMsgHdlr extends RightsManagementTrait { Users2x.findNotPresenters(liveMeeting.users2x) } - def build(meetingId: String, userId: String, muted: Boolean, mutedBy: String): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId) - val envelope = BbbCoreEnvelope(MeetingMutedEvtMsg.NAME, routing) - val header = BbbClientMsgHeader(MeetingMutedEvtMsg.NAME, meetingId, userId) - - val body = MeetingMutedEvtMsgBody(muted, mutedBy) - val event = MeetingMutedEvtMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - - def muteUserInVoiceConf(vu: VoiceUserState, mute: Boolean): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, vu.intId) - val envelope = BbbCoreEnvelope(MuteUserInVoiceConfSysMsg.NAME, routing) - val header = BbbCoreHeaderWithMeetingId(MuteUserInVoiceConfSysMsg.NAME, props.meetingProp.intId) - - val body = MuteUserInVoiceConfSysMsgBody(props.voiceProp.voiceConf, vu.voiceUserId, mute) - val event = MuteUserInVoiceConfSysMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - - outGW.send(msgEvent) - - } - } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteMeetingCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteMeetingCmdMsgHdlr.scala index 2becc88c59..4ca7e31e20 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteMeetingCmdMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/MuteMeetingCmdMsgHdlr.scala @@ -7,6 +7,7 @@ import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers } import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter } import org.bigbluebutton.core2.MeetingStatus2x import org.bigbluebutton.core2.message.senders.MsgBuilder +import org.bigbluebutton.core.apps.voice.VoiceApp trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait { this: MeetingActor => @@ -20,30 +21,6 @@ trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait { val reason = "No permission to mute meeting." PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting) } else { - def build(meetingId: String, userId: String, muted: Boolean, mutedBy: String): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId) - val envelope = BbbCoreEnvelope(MeetingMutedEvtMsg.NAME, routing) - val header = BbbClientMsgHeader(MeetingMutedEvtMsg.NAME, meetingId, userId) - - val body = MeetingMutedEvtMsgBody(muted, mutedBy) - val event = MeetingMutedEvtMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - - def muteUserInVoiceConf(vu: VoiceUserState, mute: Boolean): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, vu.intId) - val envelope = BbbCoreEnvelope(MuteUserInVoiceConfSysMsg.NAME, routing) - val header = BbbCoreHeaderWithMeetingId(MuteUserInVoiceConfSysMsg.NAME, props.meetingProp.intId) - - val body = MuteUserInVoiceConfSysMsgBody(props.voiceProp.voiceConf, vu.voiceUserId, mute) - val event = MuteUserInVoiceConfSysMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - - outGW.send(msgEvent) - - } - if (msg.body.mute != MeetingStatus2x.isMeetingMuted(liveMeeting.status)) { if (msg.body.mute) { val notifyEvent = MsgBuilder.buildNotifyAllInMeetingEvtMsg( @@ -74,7 +51,12 @@ trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait { } val muted = MeetingStatus2x.isMeetingMuted(liveMeeting.status) - val meetingMutedEvent = build(props.meetingProp.intId, msg.body.mutedBy, muted, msg.body.mutedBy) + val meetingMutedEvent = MsgBuilder.buildMeetingMutedEvtMsg( + props.meetingProp.intId, + msg.body.mutedBy, + muted, + msg.body.mutedBy + ) outGW.send(meetingMutedEvent) @@ -82,7 +64,7 @@ trait MuteMeetingCmdMsgHdlr extends RightsManagementTrait { if (muted) { VoiceUsers.findAll(liveMeeting.voiceUsers) foreach { vu => if (!vu.listenOnly) { - muteUserInVoiceConf(vu, muted) + VoiceApp.muteUserInVoiceConf(liveMeeting, outGW, vu.intId, muted) } } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala deleted file mode 100755 index a52e1ed7cb..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendBreakoutTimeRemainingMsgHdlr.scala +++ /dev/null @@ -1,53 +0,0 @@ -package org.bigbluebutton.core2.message.handlers - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.api.{ EndBreakoutRoomInternalMsg, SendBreakoutTimeRemainingInternalMsg, SendTimeRemainingAuditInternalMsg } -import org.bigbluebutton.core.bus.BigBlueButtonEvent -import org.bigbluebutton.core.domain.{ MeetingEndReason, MeetingState2x } -import org.bigbluebutton.core.running.{ LiveMeeting, MeetingActor, OutMsgRouter } -import org.bigbluebutton.core.util.TimeUtil - -trait SendBreakoutTimeRemainingMsgHdlr { - this: MeetingActor => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleSendBreakoutTimeRemainingMsg(msg: SendTimeRemainingAuditInternalMsg, state: MeetingState2x): MeetingState2x = { - for { - model <- state.breakout - startedOn <- model.startedOn - } yield { - val endMeetingTime = TimeUtil.millisToSeconds(startedOn) + model.durationInSeconds - val timeRemaining = endMeetingTime - TimeUtil.millisToSeconds(System.currentTimeMillis()) - - if (!liveMeeting.props.meetingProp.isBreakout) { - // Notify parent meeting users of breakout rooms time remaining - val event = buildBreakoutRoomsTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt, 0) - outGW.send(event) - } - - // Tell all breakout rooms of time remaining so they can notify their users. - // This syncs all rooms about time remaining. - model.rooms.values.foreach { room => - eventBus.publish(BigBlueButtonEvent(room.id, SendBreakoutTimeRemainingInternalMsg(props.breakoutProps.parentId, timeRemaining.toInt, msg.timeUpdatedInMinutes))) - } - - if (timeRemaining < 0) { - endAllBreakoutRooms(eventBus, liveMeeting, state, MeetingEndReason.BREAKOUT_ENDED_EXCEEDING_DURATION) - } - } - - state - } - - def buildBreakoutRoomsTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long, timeUpdatedInMinutes: Int = 0): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used") - val envelope = BbbCoreEnvelope(BreakoutRoomsTimeRemainingUpdateEvtMsg.NAME, routing) - val body = BreakoutRoomsTimeRemainingUpdateEvtMsgBody(timeLeftInSec) - val header = BbbClientMsgHeader(BreakoutRoomsTimeRemainingUpdateEvtMsg.NAME, meetingId, "not-used") - val event = BreakoutRoomsTimeRemainingUpdateEvtMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala deleted file mode 100755 index 27c6fb14d7..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/SendTimeRemainingUpdateHdlr.scala +++ /dev/null @@ -1,29 +0,0 @@ -package org.bigbluebutton.core2.message.handlers - -import org.bigbluebutton.core.api.SendTimeRemainingAuditInternalMsg -import org.bigbluebutton.core.domain.MeetingState2x -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } -import org.bigbluebutton.core.util.TimeUtil -import org.bigbluebutton.core2.message.senders.MsgBuilder - -trait SendTimeRemainingUpdateHdlr { - this: BaseMeetingActor => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleSendTimeRemainingUpdate(msg: SendTimeRemainingAuditInternalMsg, state: MeetingState2x): MeetingState2x = { - if (state.expiryTracker.durationInMs > 0) { - val endMeetingTime = state.expiryTracker.endMeetingTime() - val timeRemaining = TimeUtil.millisToSeconds(endMeetingTime - TimeUtil.timeNowInMs()) - - if (timeRemaining > 0) { - val event = MsgBuilder.buildMeetingTimeRemainingUpdateEvtMsg(liveMeeting.props.meetingProp.intId, timeRemaining.toInt) - outGW.send(event) - } - } - - state - } - -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/GuestWaitingLeftMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/GuestWaitingLeftMsgHdlr.scala deleted file mode 100755 index 965a0a679c..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/GuestWaitingLeftMsgHdlr.scala +++ /dev/null @@ -1,18 +0,0 @@ -package org.bigbluebutton.core2.message.handlers.guests - -import org.bigbluebutton.common2.msgs.GuestWaitingLeftMsg -import org.bigbluebutton.core.apps.users.UsersApp -import org.bigbluebutton.core.models.GuestsWaiting -import org.bigbluebutton.core.running.{ BaseMeetingActor, LiveMeeting, OutMsgRouter } - -trait GuestWaitingLeftMsgHdlr { - this: BaseMeetingActor => - - val liveMeeting: LiveMeeting - val outGW: OutMsgRouter - - def handleGuestWaitingLeftMsg(msg: GuestWaitingLeftMsg): Unit = { - GuestsWaiting.remove(liveMeeting.guestsWaiting, msg.body.userId) - UsersApp.guestWaitingLeft(liveMeeting, msg.body.userId, outGW) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetGuestLobbyMessageMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetGuestLobbyMessageMsgHdlr.scala index 64074a97e2..f8068890de 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetGuestLobbyMessageMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetGuestLobbyMessageMsgHdlr.scala @@ -7,6 +7,7 @@ import org.bigbluebutton.core2.message.senders.MsgBuilder import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } import org.bigbluebutton.core.db.MeetingUsersPoliciesDAO import org.bigbluebutton.core.running.MeetingActor +import org.bigbluebutton.core.util.HtmlUtil.htmlToHtmlEntities trait SetGuestLobbyMessageMsgHdlr extends RightsManagementTrait { this: MeetingActor => @@ -20,12 +21,13 @@ trait SetGuestLobbyMessageMsgHdlr extends RightsManagementTrait { val reason = "No permission to set guest lobby message in meeting." PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting) } else { - GuestsWaiting.setGuestLobbyMessage(liveMeeting.guestsWaiting, msg.body.message) - MeetingUsersPoliciesDAO.updateGuestLobbyMessage(liveMeeting.props.meetingProp.intId, msg.body.message) + val sanitizedMessage = htmlToHtmlEntities(msg.body.message) + GuestsWaiting.setGuestLobbyMessage(liveMeeting.guestsWaiting, sanitizedMessage) + MeetingUsersPoliciesDAO.updateGuestLobbyMessage(liveMeeting.props.meetingProp.intId, sanitizedMessage) val event = MsgBuilder.buildGuestLobbyMessageChangedEvtMsg( liveMeeting.props.meetingProp.intId, msg.header.userId, - msg.body.message + sanitizedMessage ) outGW.send(event) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetPrivateGuestLobbyMessageCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetPrivateGuestLobbyMessageCmdMsgHdlr.scala index 368884f84c..201b8c275e 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetPrivateGuestLobbyMessageCmdMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/guests/SetPrivateGuestLobbyMessageCmdMsgHdlr.scala @@ -7,6 +7,7 @@ import org.bigbluebutton.core2.message.senders.MsgBuilder import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait } import org.bigbluebutton.core.db.UserStateDAO import org.bigbluebutton.core.running.MeetingActor +import org.bigbluebutton.core.util.HtmlUtil.htmlToHtmlEntities trait SetPrivateGuestLobbyMessageCmdMsgHdlr extends RightsManagementTrait { this: MeetingActor => @@ -20,13 +21,14 @@ trait SetPrivateGuestLobbyMessageCmdMsgHdlr extends RightsManagementTrait { val reason = "No permission to send private guest lobby messages." PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting) } else { - GuestsWaiting.setPrivateGuestLobbyMessage(liveMeeting.guestsWaiting, msg.body.guestId, msg.body.message) - UserStateDAO.updateGuestLobbyMessage(msg.header.meetingId, msg.body.guestId, msg.body.message) + val sanitizedMessage = htmlToHtmlEntities(msg.body.message) + GuestsWaiting.setPrivateGuestLobbyMessage(liveMeeting.guestsWaiting, msg.body.guestId, sanitizedMessage) + UserStateDAO.updateGuestLobbyMessage(msg.header.meetingId, msg.body.guestId, sanitizedMessage) val event = MsgBuilder.buildPrivateGuestLobbyMsgChangedEvtMsg( liveMeeting.props.meetingProp.intId, msg.header.userId, msg.body.guestId, - msg.body.message + sanitizedMessage ) outGW.send(event) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/meeting/DestroyMeetingSysCmdMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/meeting/DestroyMeetingSysCmdMsgHdlr.scala index 7e02198af6..f30cbd8cc0 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/meeting/DestroyMeetingSysCmdMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/handlers/meeting/DestroyMeetingSysCmdMsgHdlr.scala @@ -26,7 +26,7 @@ trait DestroyMeetingSysCmdMsgHdlr { } // Eject all users using the client. - outGW.send(MsgBuilder.buildEndAndKickAllSysMsg(liveMeeting.props.meetingProp.intId, "not-used")) + //TODO check if it should remove Graphql connections at this moment // Force stopping of voice recording if voice conf is being recorded. VoiceApp.stopRecordingVoiceConference(liveMeeting, outGW) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala index d5f0d86b15..1dc092ea89 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala @@ -1,7 +1,7 @@ package org.bigbluebutton.core2.message.senders import org.bigbluebutton.common2.domain.DefaultProps -import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, MessageTypes, NotifyAllInMeetingEvtMsg, NotifyAllInMeetingEvtMsgBody, NotifyRoleInMeetingEvtMsg, NotifyRoleInMeetingEvtMsgBody, NotifyUserInMeetingEvtMsg, NotifyUserInMeetingEvtMsgBody, Routing, ValidateConnAuthTokenSysRespMsg, ValidateConnAuthTokenSysRespMsgBody, _ } +import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, MessageTypes, NotifyAllInMeetingEvtMsg, NotifyAllInMeetingEvtMsgBody, NotifyRoleInMeetingEvtMsg, NotifyRoleInMeetingEvtMsgBody, NotifyUserInMeetingEvtMsg, NotifyUserInMeetingEvtMsgBody, Routing, _ } import org.bigbluebutton.core.models.{ GuestWaiting, PresentationPod } object MsgBuilder { @@ -97,50 +97,6 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, event) } - def buildValidateConnAuthTokenSysRespMsg(meetingId: String, userId: String, - authzed: Boolean, connId: String, app: String): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId) - val envelope = BbbCoreEnvelope(ValidateConnAuthTokenSysRespMsg.NAME, routing) - val header = BbbCoreHeaderWithMeetingId(ValidateConnAuthTokenSysRespMsg.NAME, meetingId) - val body = ValidateConnAuthTokenSysRespMsgBody(meetingId, userId, connId, authzed, app) - val event = ValidateConnAuthTokenSysRespMsg(header, body) - BbbCommonEnvCoreMsg(envelope, event) - } - - def buildValidateAuthTokenRespMsg(meetingId: String, userId: String, authToken: String, - valid: Boolean, waitForApproval: Boolean, registeredOn: Long, authTokenValidatedOn: Long, - reasonCode: String, reason: String): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId) - val envelope = BbbCoreEnvelope(ValidateAuthTokenRespMsg.NAME, routing) - val header = BbbClientMsgHeader(ValidateAuthTokenRespMsg.NAME, meetingId, userId) - val body = ValidateAuthTokenRespMsgBody(userId, authToken, valid, waitForApproval, registeredOn, authTokenValidatedOn, - reasonCode, reason) - val event = ValidateAuthTokenRespMsg(header, body) - BbbCommonEnvCoreMsg(envelope, event) - } - - def buildGetUsersMeetingRespMsg(meetingId: String, userId: String, webusers: Vector[WebUser]): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId) - val envelope = BbbCoreEnvelope(GetUsersMeetingRespMsg.NAME, routing) - val header = BbbClientMsgHeader(GetUsersMeetingRespMsg.NAME, meetingId, userId) - - val body = GetUsersMeetingRespMsgBody(webusers) - val event = GetUsersMeetingRespMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - - def buildGetVoiceUsersMeetingRespMsg(meetingId: String, userId: String, voiceUsers: Vector[VoiceConfUser]): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId) - val envelope = BbbCoreEnvelope(GetVoiceUsersMeetingRespMsg.NAME, routing) - val header = BbbClientMsgHeader(GetVoiceUsersMeetingRespMsg.NAME, meetingId, userId) - - val body = GetVoiceUsersMeetingRespMsgBody(voiceUsers) - val event = GetVoiceUsersMeetingRespMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - def buildPresenterAssignedEvtMsg(meetingId: String, intId: String, name: String, assignedBy: String): BbbCommonEnvCoreMsg = { val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, intId) val envelope = BbbCoreEnvelope(PresenterAssignedEvtMsg.NAME, routing) @@ -216,16 +172,6 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, event) } - def buildEndAndKickAllSysMsg(meetingId: String, userId: String): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.SYSTEM, meetingId, userId) - val envelope = BbbCoreEnvelope(EndAndKickAllSysMsg.NAME, routing) - val body = EndAndKickAllSysMsgBody(meetingId) - val header = BbbCoreHeaderWithMeetingId(EndAndKickAllSysMsg.NAME, meetingId) - val event = EndAndKickAllSysMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - def buildRecordStatusResetSysMsg(meetingId: String, recording: Boolean, setBy: String): BbbCommonEnvCoreMsg = { val routing = Routing.addMsgToClientRouting(MessageTypes.SYSTEM, meetingId, setBy) val envelope = BbbCoreEnvelope(RecordStatusResetSysMsg.NAME, routing) @@ -276,16 +222,6 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, event) } - def buildDisconnectClientSysMsg(meetingId: String, userId: String, ejectedBy: String, reason: String): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.SYSTEM, meetingId, userId) - val envelope = BbbCoreEnvelope(DisconnectClientSysMsg.NAME, routing) - val header = BbbCoreHeaderWithMeetingId(DisconnectClientSysMsg.NAME, meetingId) - val body = DisconnectClientSysMsgBody(meetingId, userId, ejectedBy, reason) - val event = DisconnectClientSysMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - def buildGuestWaitingLeftEvtMsg(meetingId: String, userId: String): BbbCommonEnvCoreMsg = { val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId) val envelope = BbbCoreEnvelope(GuestWaitingLeftEvtMsg.NAME, routing) @@ -346,6 +282,17 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, event) } + def buildMeetingMutedEvtMsg(meetingId: String, userId: String, muted: Boolean, mutedBy: String): BbbCommonEnvCoreMsg = { + val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId) + val envelope = BbbCoreEnvelope(MeetingMutedEvtMsg.NAME, routing) + val header = BbbClientMsgHeader(MeetingMutedEvtMsg.NAME, meetingId, userId) + + val body = MeetingMutedEvtMsgBody(muted, mutedBy) + val event = MeetingMutedEvtMsg(header, body) + + BbbCommonEnvCoreMsg(envelope, event) + } + def buildMuteUserInVoiceConfSysMsg(meetingId: String, voiceConf: String, voiceUserId: String, mute: Boolean): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") val envelope = BbbCoreEnvelope(MuteUserInVoiceConfSysMsg.NAME, routing) @@ -511,16 +458,6 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, event) } - def buildMeetingTimeRemainingUpdateEvtMsg(meetingId: String, timeLeftInSec: Long, timeUpdatedInMinutes: Int = 0): BbbCommonEnvCoreMsg = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, "not-used") - val envelope = BbbCoreEnvelope(MeetingTimeRemainingUpdateEvtMsg.NAME, routing) - val body = MeetingTimeRemainingUpdateEvtMsgBody(timeLeftInSec, timeUpdatedInMinutes) - val header = BbbClientMsgHeader(MeetingTimeRemainingUpdateEvtMsg.NAME, meetingId, "not-used") - val event = MeetingTimeRemainingUpdateEvtMsg(header, body) - - BbbCommonEnvCoreMsg(envelope, event) - } - def buildLearningDashboardEvtMsg(meetingId: String, learningDashboardAccessToken: String, activityJson: String): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") val envelope = BbbCoreEnvelope(LearningDashboardEvtMsg.NAME, routing) @@ -611,15 +548,6 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, event) } - def buildUserEmojiChangedEvtMsg(meetingId: String, userId: String, emoji: String) = { - val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId) - val envelope = BbbCoreEnvelope(UserEmojiChangedEvtMsg.NAME, routing) - val header = BbbClientMsgHeader(UserEmojiChangedEvtMsg.NAME, meetingId, userId) - val body = UserEmojiChangedEvtMsgBody(userId, emoji) - val event = UserEmojiChangedEvtMsg(header, body) - BbbCommonEnvCoreMsg(envelope, event) - } - def buildUserAwayChangedEvtMsg(meetingId: String, userId: String, away: Boolean) = { val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId) val envelope = BbbCoreEnvelope(UserAwayChangedEvtMsg.NAME, routing) @@ -657,11 +585,12 @@ object MsgBuilder { meetingId: String, voiceConf: String, userId: String, + callerNum: String, enabled: Boolean ): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka") val envelope = BbbCoreEnvelope(ToggleListenOnlyModeSysMsg.NAME, routing) - val body = ToggleListenOnlyModeSysMsgBody(voiceConf, userId, enabled) + val body = ToggleListenOnlyModeSysMsgBody(voiceConf, userId, callerNum, enabled) val header = BbbCoreHeaderWithMeetingId(ToggleListenOnlyModeSysMsg.NAME, meetingId) val event = ToggleListenOnlyModeSysMsg(header, body) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/Sender.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/Sender.scala index b0da37c24f..1a93944213 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/Sender.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/Sender.scala @@ -4,12 +4,6 @@ import org.bigbluebutton.core.running.OutMsgRouter object Sender { - def sendDisconnectClientSysMsg(meetingId: String, userId: String, - ejectedBy: String, reason: String, outGW: OutMsgRouter): Unit = { - val ejectFromMeetingSystemEvent = MsgBuilder.buildDisconnectClientSysMsg(meetingId, userId, ejectedBy, reason) - outGW.send(ejectFromMeetingSystemEvent) - } - def sendForceUserGraphqlReconnectionSysMsg(meetingId: String, userId: String, sessionToken: String, reason: String, outGW: OutMsgRouter): Unit = { val ForceUserGraphqlReconnectionSysMsg = MsgBuilder.buildForceUserGraphqlReconnectionSysMsg(meetingId, userId, sessionToken, reason) outGW.send(ForceUserGraphqlReconnectionSysMsg) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/UserJoinedMeetingEvtMsgBuilder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/UserJoinedMeetingEvtMsgBuilder.scala index 4301e11fc3..c79d0abe52 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/UserJoinedMeetingEvtMsgBuilder.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/UserJoinedMeetingEvtMsgBuilder.scala @@ -11,13 +11,13 @@ object UserJoinedMeetingEvtMsgBuilder { val body = UserJoinedMeetingEvtMsgBody(intId = userState.intId, extId = userState.extId, name = userState.name, role = userState.role, guest = userState.guest, authed = userState.authed, guestStatus = userState.guestStatus, - emoji = userState.emoji, reactionEmoji = userState.reactionEmoji, raiseHand = userState.raiseHand, away = userState.away, pin = userState.pin, - presenter = userState.presenter, locked = userState.locked, avatar = userState.avatar, color = userState.color, - clientType = userState.clientType) + presenter = userState.presenter, locked = userState.locked, avatar = userState.avatar, webcamBackground = userState.webcamBackground, color = userState.color, + clientType = userState.clientType, + userMetadata = userState.userMetadata) val event = UserJoinedMeetingEvtMsg(meetingId, userState.intId, body) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/ValidateAuthTokenRespMsgSender.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/ValidateAuthTokenRespMsgSender.scala deleted file mode 100755 index 51eb640da2..0000000000 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/ValidateAuthTokenRespMsgSender.scala +++ /dev/null @@ -1,18 +0,0 @@ -package org.bigbluebutton.core2.message.senders - -import org.bigbluebutton.common2.msgs._ -import org.bigbluebutton.core.running.OutMsgRouter - -object ValidateAuthTokenRespMsgSender { - - def send(outGW: OutMsgRouter, meetingId: String, userId: String, authToken: String, - valid: Boolean, waitForApproval: Boolean, registeredOn: Long, authTokenValidatedOn: Long, reasonCode: String, reason: String): Unit = { - val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId) - val envelope = BbbCoreEnvelope(ValidateAuthTokenRespMsg.NAME, routing) - val header = BbbClientMsgHeader(ValidateAuthTokenRespMsg.NAME, meetingId, userId) - val body = ValidateAuthTokenRespMsgBody(userId, authToken, valid, waitForApproval, registeredOn, authTokenValidatedOn, reasonCode, reason) - val event = ValidateAuthTokenRespMsg(header, body) - val msgEvent = BbbCommonEnvCoreMsg(envelope, event) - outGW.send(msgEvent) - } -} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeTestData.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeTestData.scala index d6ab0becf4..2b73e0ba84 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeTestData.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeTestData.scala @@ -20,13 +20,13 @@ trait FakeTestData { val guest1 = createUserVoiceAndCam(liveMeeting, Roles.VIEWER_ROLE, guest = true, authed = true, CallingWith.WEBRTC, muted = false, talking = false, listenOnly = false) Users2x.add(liveMeeting.users2x, guest1) - val guestWait1 = GuestWaiting(guest1.intId, guest1.name, guest1.role, guest1.guest, "", "#ff6242", guest1.authed, System.currentTimeMillis()) + val guestWait1 = GuestWaiting(guest1.intId, guest1.name, guest1.role, guest1.guest, "", "", "#ff6242", guest1.authed, System.currentTimeMillis()) GuestsWaiting.add(liveMeeting.guestsWaiting, guestWait1) val guest2 = createUserVoiceAndCam(liveMeeting, Roles.VIEWER_ROLE, guest = true, authed = true, CallingWith.FLASH, muted = false, talking = false, listenOnly = false) Users2x.add(liveMeeting.users2x, guest2) - val guestWait2 = GuestWaiting(guest2.intId, guest2.name, guest2.role, guest2.guest, "", "#ff6242", guest2.authed, System.currentTimeMillis()) + val guestWait2 = GuestWaiting(guest2.intId, guest2.name, guest2.role, guest2.guest, "", "", "#ff6242", guest2.authed, System.currentTimeMillis()) GuestsWaiting.add(liveMeeting.guestsWaiting, guestWait2) val meetingId = liveMeeting.props.meetingProp.intId @@ -71,8 +71,8 @@ trait FakeTestData { UserState(intId = regUser.id, extId = regUser.externId, meetingId = regUser.meetingId, name = regUser.name, role = regUser.role, pin = false, mobile = false, guest = regUser.guest, authed = regUser.authed, guestStatus = regUser.guestStatus, - emoji = "none", reactionEmoji = "none", raiseHand = false, away = false, locked = false, presenter = false, - avatar = regUser.avatarURL, color = "#ff6242", clientType = "unknown", userLeftFlag = UserLeftFlag(false, 0)) + reactionEmoji = "none", raiseHand = false, away = false, locked = false, presenter = false, + avatar = regUser.avatarURL, webcamBackground = regUser.webcamBackgroundURL, color = "#ff6242", clientType = "unknown", userLeftFlag = UserLeftFlag(false, 0)) } } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeUserGenerator.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeUserGenerator.scala index 24124473a6..24ae0f4a85 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeUserGenerator.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/testdata/FakeUserGenerator.scala @@ -53,10 +53,12 @@ object FakeUserGenerator { val sessionToken = RandomStringGenerator.randomAlphanumericString(16) val avatarURL = "https://www." + RandomStringGenerator.randomAlphanumericString(32) + ".com/" + RandomStringGenerator.randomAlphanumericString(10) + ".png" + val webcamBackgroundURL = "https://www." + RandomStringGenerator.randomAlphanumericString(32) + ".com/" + + RandomStringGenerator.randomAlphanumericString(10) + ".jpg" val color = "#ff6242" val ru = RegisteredUsers.create(meetingId, userId = id, extId, name, role, - authToken, sessionToken, avatarURL, color, guest, authed, guestStatus = GuestStatus.ALLOW, false, "", Map(), false) + authToken, sessionToken, avatarURL, webcamBackgroundURL, color, guest, authed, guestStatus = GuestStatus.ALLOW, false, "", Map(), false) RegisteredUsers.add(users, ru, meetingId) ru } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/GraphqlConnectionsActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/GraphqlConnectionsActor.scala index 2bf507ff6a..64efa9e9df 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/GraphqlConnectionsActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/GraphqlConnectionsActor.scala @@ -37,6 +37,9 @@ case class GraphqlUserConnection( middlewareUID: String, browserConnectionId: String, sessionToken: String, + clientSessionUUID: String, + clientType: String, + clientIsMobile: Boolean, user: GraphqlUser, ) @@ -88,21 +91,33 @@ class GraphqlConnectionsActor( } private def handleUserGraphqlConnectionEstablishedSysMsg(msg: UserGraphqlConnectionEstablishedSysMsg): Unit = { - UserGraphqlConnectionDAO.insert(msg.body.sessionToken, msg.body.middlewareUID, msg.body.browserConnectionId) + UserGraphqlConnectionDAO.insert( + msg.body.sessionToken, + msg.body.clientSessionUUID, + msg.body.clientType, + msg.body.clientIsMobile, + msg.body.middlewareUID, + msg.body.browserConnectionId) for { user <- users.get(msg.body.sessionToken) } yield { //Send internal message informing user has connected - if (!graphqlConnections.values.exists(c => c.sessionToken == msg.body.sessionToken)) { - eventBus.publish(BigBlueButtonEvent(user.meetingId, UserEstablishedGraphqlConnectionInternalMsg(user.intId))) - } + eventBus.publish(BigBlueButtonEvent(user.meetingId, + UserEstablishedGraphqlConnectionInternalMsg( + user.intId, + msg.body.clientType, + msg.body.clientIsMobile) + )) graphqlConnections += (msg.body.browserConnectionId -> GraphqlUserConnection( msg.body.middlewareUID, msg.body.browserConnectionId, msg.body.sessionToken, + msg.body.clientSessionUUID, + msg.body.clientType, + msg.body.clientIsMobile, user )) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/LearningDashboardActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/LearningDashboardActor.scala index 6d95edf142..3c0f7b45f6 100644 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/LearningDashboardActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/LearningDashboardActor.scala @@ -22,6 +22,7 @@ case class Meeting( name: String, downloadSessionDataEnabled: Boolean, users: Map[String, User] = Map(), + genericDataTitles: Vector[String], polls: Map[String, Poll] = Map(), screenshares: Vector[Screenshare] = Vector(), presentationSlides: Vector[PresentationSlide] = Vector(), @@ -30,19 +31,21 @@ case class Meeting( ) case class User( - userKey: String, - extId: String, - intIds: Map[String,UserId] = Map(), - name: String, - isModerator: Boolean, - isDialIn: Boolean = false, - currentIntId: String = null, - answers: Map[String,Vector[String]] = Map(), - talk: Talk = Talk(), - emojis: Vector[Emoji] = Vector(), - reactions: Vector[Emoji] = Vector(), - webcams: Vector[Webcam] = Vector(), - totalOfMessages: Long = 0, + userKey: String, + extId: String, + intIds: Map[String,UserId] = Map(), + name: String, + isModerator: Boolean, + isDialIn: Boolean = false, + currentIntId: String = null, + answers: Map[String,Vector[String]] = Map(), + genericData: Map[String, Vector[GenericData]] = Map(), + talk: Talk = Talk(), + reactions: Vector[Reaction] = Vector(), + raiseHand: Vector[Long] = Vector(), + away: Vector[Away] = Vector(), + webcams: Vector[Webcam] = Vector(), + totalOfMessages: Long = 0, ) case class UserId( @@ -63,16 +66,26 @@ case class Poll( createdOn: Long = System.currentTimeMillis(), ) +case class GenericData( + columnTitle: String, + value: String, +) + case class Talk( totalTime: Long = 0, lastTalkStartedOn: Long = 0, ) -case class Emoji( +case class Reaction( name: String, sentOn: Long = System.currentTimeMillis(), ) +case class Away( + startedOn: Long = System.currentTimeMillis(), + stoppedOn: Long = 0, +) + case class Webcam( startedOn: Long = System.currentTimeMillis(), stoppedOn: Long = 0, @@ -141,7 +154,6 @@ class LearningDashboardActor( case m: UserJoinMeetingReqMsg => handleUserJoinMeetingReqMsg(m) case m: UserLeaveReqMsg => handleUserLeaveReqMsg(m) case m: UserLeftMeetingEvtMsg => handleUserLeftMeetingEvtMsg(m) - case m: UserEmojiChangedEvtMsg => handleUserEmojiChangedEvtMsg(m) case m: UserAwayChangedEvtMsg => handleUserAwayChangedEvtMsg(m) case m: UserRaiseHandChangedEvtMsg => handleUserRaiseHandChangedEvtMsg(m) case m: UserReactionEmojiChangedEvtMsg => handleUserReactionEmojiChangedEvtMsg(m) @@ -155,6 +167,10 @@ class LearningDashboardActor( case m: UserMutedVoiceEvtMsg => handleUserMutedVoiceEvtMsg(m) case m: UserTalkingVoiceEvtMsg => handleUserTalkingVoiceEvtMsg(m) + // Plugin + case m: PluginLearningAnalyticsDashboardSendGenericDataMsg => + handlePluginLearningAnalyticsDashboardSendGenericDataMsg(m) + // Screenshare case m: ScreenshareRtmpBroadcastStartedEvtMsg => handleScreenshareRtmpBroadcastStartedEvtMsg(m) case m: ScreenshareRtmpBroadcastStoppedEvtMsg => handleScreenshareRtmpBroadcastStoppedEvtMsg(m) @@ -350,27 +366,13 @@ class LearningDashboardActor( } } - private def handleUserEmojiChangedEvtMsg(msg: UserEmojiChangedEvtMsg): Unit = { - for { - meeting <- meetings.values.find(m => m.intId == msg.header.meetingId) - user <- findUserByIntId(meeting, msg.body.userId) - } yield { - if (msg.body.emoji != "none" && msg.body.emoji != "raiseHand" && msg.body.emoji != "away") { - val updatedUser = user.copy(emojis = user.emojis :+ Emoji(msg.body.emoji)) - val updatedMeeting = meeting.copy(users = meeting.users + (updatedUser.userKey -> updatedUser)) - - meetings += (updatedMeeting.intId -> updatedMeeting) - } - } - } - private def handleUserRaiseHandChangedEvtMsg(msg: UserRaiseHandChangedEvtMsg): Unit = { for { meeting <- meetings.values.find(m => m.intId == msg.header.meetingId) user <- findUserByIntId(meeting, msg.body.userId) } yield { if (msg.body.raiseHand) { - val updatedUser = user.copy(emojis = user.emojis :+ Emoji("raiseHand")) + val updatedUser = user.copy(raiseHand = user.raiseHand :+ System.currentTimeMillis()) val updatedMeeting = meeting.copy(users = meeting.users + (updatedUser.userKey -> updatedUser)) meetings += (updatedMeeting.intId -> updatedMeeting) @@ -383,12 +385,24 @@ class LearningDashboardActor( meeting <- meetings.values.find(m => m.intId == msg.header.meetingId) user <- findUserByIntId(meeting, msg.body.userId) } yield { - if (msg.body.away) { - val updatedUser = user.copy(emojis = user.emojis :+ Emoji("away")) - val updatedMeeting = meeting.copy(users = meeting.users + (updatedUser.userKey -> updatedUser)) - - meetings += (updatedMeeting.intId -> updatedMeeting) + val updatedUser = if (msg.body.away) { + if (user.away.exists(a => a.stoppedOn == 0)) { + //do nothing if user is already away + user + } else { + user.copy(away = user.away :+ Away()) + } + } else { + if(user.away.last.stoppedOn == 0) { + user.copy(away = user.away.dropRight(1) :+ user.away.last.copy(stoppedOn = System.currentTimeMillis())) + } else { + //do nothing if user is not away + user + } } + + val updatedMeeting = meeting.copy(users = meeting.users + (updatedUser.userKey -> updatedUser)) + meetings += (updatedMeeting.intId -> updatedMeeting) } } @@ -404,26 +418,9 @@ class LearningDashboardActor( }).length > 0 if(!hasSameReactionInLast30Seconds) { - val updatedUser = user.copy(reactions = user.reactions :+ Emoji(msg.body.reactionEmoji)) + val updatedUser = user.copy(reactions = user.reactions :+ Reaction(msg.body.reactionEmoji)) val updatedMeeting = meeting.copy(users = meeting.users + (updatedUser.userKey -> updatedUser)) meetings += (updatedMeeting.intId -> updatedMeeting) - - //Convert Reactions to legacy Emoji (while LearningDashboard doesn't support Reactions) - val emoji = msg.body.reactionEmoji.codePointAt(0) match { - case 128515 => "happy" - case 128528 => "neutral" - case 128577 => "sad" - case 128077 => "thumbsUp" - case 128078 => "thumbsDown" - case 128079 => "applause" - case _ => "none" - } - - if (emoji != "none") { - val updatedUserWithEmoji = updatedUser.copy(emojis = user.emojis :+ Emoji(emoji)) - val updatedMeetingWithEmoji = meeting.copy(users = meeting.users + (updatedUserWithEmoji.userKey -> updatedUserWithEmoji)) - meetings += (updatedMeeting.intId -> updatedMeetingWithEmoji) - } } } } @@ -570,6 +567,28 @@ class LearningDashboardActor( } } + private def handlePluginLearningAnalyticsDashboardSendGenericDataMsg(msg: PluginLearningAnalyticsDashboardSendGenericDataMsg) = { + for { + meeting <- meetings.values.find(m => m.intId == msg.header.meetingId) + user <- findUserByIntId(meeting, msg.header.userId) + } yield { + val currentUserGenericData = user.genericData.getOrElse(msg.body.genericDataForLearningAnalyticsDashboard.cardTitle,Vector()) + val newGenericDataEntry = GenericData(msg.body.genericDataForLearningAnalyticsDashboard.columnTitle, msg.body.genericDataForLearningAnalyticsDashboard.value) + val updatedUser = user.copy(genericData = user.genericData + (msg.body.genericDataForLearningAnalyticsDashboard.cardTitle -> (currentUserGenericData :+ newGenericDataEntry))) + + val updatedGenericDataTitles = if(!meeting.genericDataTitles.contains(msg.body.genericDataForLearningAnalyticsDashboard.cardTitle)) { + meeting.genericDataTitles :+ msg.body.genericDataForLearningAnalyticsDashboard.cardTitle + } else { + meeting.genericDataTitles + } + + val updatedMeeting = meeting.copy(users = meeting.users + (updatedUser.userKey -> updatedUser), genericDataTitles = updatedGenericDataTitles) + + meetings += (updatedMeeting.intId -> updatedMeeting) + log.debug("New generic data received from a plugin '{}': {}", msg.body.pluginName,msg.body.genericDataForLearningAnalyticsDashboard) + } + } + private def handleScreenshareRtmpBroadcastStoppedEvtMsg(msg: ScreenshareRtmpBroadcastStoppedEvtMsg) { for { meeting <- meetings.values.find(m => m.intId == msg.header.meetingId) @@ -587,6 +606,7 @@ class LearningDashboardActor( msg.body.props.meetingProp.extId, msg.body.props.meetingProp.name, downloadSessionDataEnabled = !msg.body.props.meetingProp.disabledFeatures.contains("learningDashboardDownloadSessionData"), + genericDataTitles = Vector() ) meetings += (newMeeting.intId -> newMeeting) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala index 628b88c251..10d8807c53 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala @@ -84,7 +84,6 @@ class RedisRecorderActor( case m: UserJoinedMeetingEvtMsg => handleUserJoinedMeetingEvtMsg(m) case m: UserLeftMeetingEvtMsg => handleUserLeftMeetingEvtMsg(m) case m: PresenterAssignedEvtMsg => handlePresenterAssignedEvtMsg(m) - case m: UserEmojiChangedEvtMsg => handleUserEmojiChangedEvtMsg(m) case m: UserAwayChangedEvtMsg => handleUserAwayChangedEvtMsg(m) case m: UserRaiseHandChangedEvtMsg => handleUserRaiseHandChangedEvtMsg(m) case m: UserReactionEmojiChangedEvtMsg => handleUserReactionEmojiChangedEvtMsg(m) @@ -116,7 +115,7 @@ class RedisRecorderActor( case m: RecordingStatusChangedEvtMsg => handleRecordingStatusChangedEvtMsg(m) case m: RecordStatusResetSysMsg => handleRecordStatusResetSysMsg(m) case m: WebcamsOnlyForModeratorChangedEvtMsg => handleWebcamsOnlyForModeratorChangedEvtMsg(m) - case m: MeetingEndingEvtMsg => handleEndAndKickAllSysMsg(m) + case m: MeetingEndingEvtMsg => handleMeetingEndingEvtMsg(m) case m: MeetingCreatedEvtMsg => handleStarterConfigurations(m) // Recording @@ -352,6 +351,7 @@ class RedisRecorderActor( ev.setExternalUserId(msg.body.extId) ev.setName(msg.body.name) ev.setRole(msg.body.role) + ev.setUserdata(msg.body.userMetadata) record(msg.header.meetingId, ev.toMap.asJava) } @@ -373,9 +373,6 @@ class RedisRecorderActor( record(msg.header.meetingId, ev.toMap.asJava) } - private def handleUserEmojiChangedEvtMsg(msg: UserEmojiChangedEvtMsg) { - handleUserStatusChange(msg.header.meetingId, msg.body.userId, "emojiStatus", msg.body.emoji) - } private def handleUserAwayChangedEvtMsg(msg: UserAwayChangedEvtMsg) { handleUserStatusChange(msg.header.meetingId, msg.body.userId, "away", if (msg.body.away) "true" else "false") @@ -640,7 +637,7 @@ class RedisRecorderActor( record(msg.header.meetingId, ev.toMap.asJava) } - private def handleEndAndKickAllSysMsg(msg: MeetingEndingEvtMsg): Unit = { + private def handleMeetingEndingEvtMsg(msg: MeetingEndingEvtMsg): Unit = { val ev = new EndAndKickAllRecordEvent() ev.setMeetingId(msg.header.meetingId) ev.setReason(msg.body.reason) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/service/UserInfoService.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/service/UserInfoService.scala new file mode 100755 index 0000000000..da71f8ec54 --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/service/UserInfoService.scala @@ -0,0 +1,81 @@ +package org.bigbluebutton.service + +import org.apache.pekko.actor.{ActorRef, ActorSystem} +import org.apache.pekko.http.scaladsl.model.headers.RawHeader +import org.apache.pekko.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCode} +import org.apache.pekko.pattern.ask +import org.apache.pekko.pattern.AskTimeoutException +import org.apache.pekko.util.Timeout +import org.bigbluebutton.common2.util.JsonUtil +import org.bigbluebutton.core.api.{ApiResponse, ApiResponseFailure, GetUserApiMsg, UserInfosApiMsg} + +import scala.concurrent.duration.DurationInt +import scala.concurrent.{ExecutionContextExecutor, Future} + + +object UserInfoService { + def apply(system: ActorSystem, bbbActor: ActorRef) = new UserInfoService(system, bbbActor) +} + +class UserInfoService(system: ActorSystem, bbbActor: ActorRef) { + implicit def executionContext: ExecutionContextExecutor = system.dispatcher + implicit val timeout: Timeout = 2 seconds + + def getUserInfo(sessionToken: String): Future[ApiResponse] = { + val future = bbbActor.ask(GetUserApiMsg(sessionToken)).mapTo[ApiResponse] + + future.recover { + case e: AskTimeoutException => ApiResponseFailure("Request Timeout error") + } + } + + def generateResponseMap(userInfos: UserInfosApiMsg): Map[String, Any] = { + val infos = userInfos.infos + val meetingID = infos.getOrElse("meetingID", "").toString + val userId = infos.getOrElse("internalUserID", "").toString + + def conditionalValue(key: String, defaultValueTrue: String, defaultValueFalse: String): String = { + infos.get(key) match { + case Some(value: Boolean) if value => defaultValueTrue + case _ => defaultValueFalse + } + } + + if (conditionalValue("currentlyInMeeting", "true", "false") == "true") { + Map( + "response" -> "authorized", + "X-Hasura-Role" -> "bbb_client", + "X-Hasura-ModeratorInMeeting" -> conditionalValue("moderator", meetingID, ""), + "X-Hasura-PresenterInMeeting" -> conditionalValue("presenter", meetingID, ""), + "X-Hasura-UserId" -> userId, + "X-Hasura-MeetingId" -> meetingID, + "X-Hasura-CursorNotLockedInMeeting" -> conditionalValue("hideViewersCursor", "", meetingID), + "X-Hasura-CursorLockedUserId" -> conditionalValue("hideViewersCursor", userId, ""), + "X-Hasura-AnnotationsNotLockedInMeeting" -> conditionalValue("hideViewersAnnotation", "", meetingID), + "X-Hasura-AnnotationsLockedUserId" -> conditionalValue("hideViewersAnnotation", userId, ""), + "X-Hasura-UserListNotLockedInMeeting" -> conditionalValue("hideUserList", "", meetingID), + "X-Hasura-WebcamsNotLockedInMeeting" -> conditionalValue("webcamsOnlyForModerator", "", meetingID), + "X-Hasura-WebcamsLockedUserId" -> conditionalValue("webcamsOnlyForModerator", userId, "") + ) + } else { + Map( + "response" -> "authorized", + "X-Hasura-Role" -> "bbb_client_not_in_meeting", + "X-Hasura-ModeratorInMeeting" -> conditionalValue("moderator", meetingID, ""), + "X-Hasura-PresenterInMeeting" -> conditionalValue("presenter", meetingID, ""), + "X-Hasura-UserId" -> userId, + "X-Hasura-MeetingId" -> meetingID, + ) + } + + } + + def createHttpResponse(status: StatusCode, response: Map[String, Any]): HttpResponse = { + HttpResponse( + status, + headers = Seq(RawHeader("Cache-Control", "no-cache")), + entity = HttpEntity(ContentTypes.`application/json`, JsonUtil.toJson(response)) + ) + } + +} diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala index 7bb4243f73..b89b956b4a 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core/AppsTestFixtures.scala @@ -37,7 +37,7 @@ trait AppsTestFixtures { val isBreakout = false val welcomeMsgTemplate = "Welcome message template" val welcomeMsg = "Welcome message" - val modOnlyMessage = "Moderator only message" + val welcomeMsgForModerators = "Moderator only message" val dialNumber = "613-555-1234" val maxUsers = 25 val guestPolicy = "ALWAYS_ASK" @@ -65,8 +65,7 @@ trait AppsTestFixtures { val password = PasswordProp(moderatorPass = moderatorPassword, viewerPass = viewerPassword, learningDashboardAccessToken = learningDashboardAccessToken) val recordProp = RecordProp(record = record, autoStartRecording = autoStartRecording, allowStartStopRecording = allowStartStopRecording, keepEvents = keepEvents ) - val welcomeProp = WelcomeProp(welcomeMsgTemplate = welcomeMsgTemplate, welcomeMsg = welcomeMsg, - modOnlyMessage = modOnlyMessage) + val welcomeProp = WelcomeProp(welcomeMsg = welcomeMsg, welcomeMsgForModerators = welcomeMsgForModerators) val voiceProp = VoiceProp(telVoice = voiceConfId, voiceConf = voiceConfId, dialNumber = dialNumber, muteOnStart = muteOnStart) val usersProp = UsersProp(maxUsers = maxUsers, webcamsOnlyForModerator = webcamsOnlyForModerator, userCameraCap = userCameraCap, diff --git a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala index 375a47582d..af958d14d0 100755 --- a/akka-bbb-apps/src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala +++ b/akka-bbb-apps/src/test/scala/org/bigbluebutton/core2/testdata/TestDataGen.scala @@ -13,10 +13,12 @@ object TestDataGen { val sessionToken = RandomStringGenerator.randomAlphanumericString(16) val avatarURL = "https://www." + RandomStringGenerator.randomAlphanumericString(32) + ".com/" + RandomStringGenerator.randomAlphanumericString(10) + ".png" + val webcamBackgroundURL = "https://www." + RandomStringGenerator.randomAlphanumericString(32) + ".com/" + + RandomStringGenerator.randomAlphanumericString(10) + ".jpg" val color = "#ff6242" val ru = RegisteredUsers.create(meetingId, userId = id, extId, name, role, - authToken, sessionToken, avatarURL, color, guest, authed, GuestStatus.ALLOW, false, "", Map(), false) + authToken, sessionToken, avatarURL, webcamBackgroundURL, color, guest, authed, GuestStatus.ALLOW, false, "", Map(), false) RegisteredUsers.add(users, ru, meetingId = "test") ru @@ -75,8 +77,8 @@ object TestDataGen { def createUserFor(liveMeeting: LiveMeeting, regUser: RegisteredUser, presenter: Boolean): UserState = { val u = UserState(intId = regUser.id, extId = regUser.externId, meetingId = regUser.meetingId, name = regUser.name, role = regUser.role, guest = regUser.guest, authed = regUser.authed, guestStatus = regUser.guestStatus, - emoji = "none", reactionEmoji = "none", raiseHand = false, away = false, pin = false, mobile = false, - locked = false, presenter = false, avatar = regUser.avatarURL, color = "#ff6242", + reactionEmoji = "none", raiseHand = false, away = false, pin = false, mobile = false, + locked = false, presenter = false, avatar = regUser.avatarURL, regUser.webcamBackgroundURL, color = "#ff6242", clientType = "unknown", userLeftFlag = UserLeftFlag(false, 0)) Users2x.add(liveMeeting.users2x, u) u diff --git a/akka-bbb-apps/src/universal/conf/application.conf b/akka-bbb-apps/src/universal/conf/application.conf index ec5046bbb7..d63c77ba84 100755 --- a/akka-bbb-apps/src/universal/conf/application.conf +++ b/akka-bbb-apps/src/universal/conf/application.conf @@ -9,7 +9,7 @@ pekko { } loggers = ["org.apache.pekko.event.slf4j.Slf4jLogger"] loglevel = "DEBUG" - + redis-publish-worker-dispatcher { mailbox-type = "org.apache.pekko.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be @@ -17,7 +17,7 @@ pekko { # Set to 1 for as fair as possible. throughput = 512 } - + redis-subscriber-worker-dispatcher { mailbox-type = "org.apache.pekko.dispatch.SingleConsumerOnlyUnboundedMailbox" # Throughput defines the maximum number of messages to be @@ -28,7 +28,7 @@ pekko { } client { - clientSettingsFilePath = "/usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml" + clientSettingsFilePath = "/var/bigbluebutton/html5-client/private/config/settings.yml" clientSettingsOverrideFilePath = "/etc/bigbluebutton/bbb-html5.yml" } @@ -104,6 +104,11 @@ voiceConf { # Use ogg instead of wav to get smaller audio files. # Valid values "wav", "ogg", "flac", "opus" recordCodec = "opus" + # FreeSWITCH sometimes loses audio frames in long recordings + # this enable split audio recording in smaller files + recordEnableFileSplitter = false + # Duration of each recorded audio file if splitter is enabled + recordFileSplitterIntervalInMinutes = 15 # Interval seconds to check if FreeSWITCH is recording. checkRecordingInterval = 23 # Internval seconds to sync voice users status. @@ -118,6 +123,20 @@ voiceConf { # Time (seconds) to wait before requesting an audio channel hold after # muting a user. Used in the experimental, transparent listen only mode. toggleListenOnlyAfterMuteTimer = 4 + + # Transparent listen only meeting-wide activation threshold. + # Threshold is the number of muted duplex audio channels in a meeting. + # 0 = disabled + transparentListenOnlyThreshold = 0 + + # muteOnStartThreshold: forces muteOnStart=true for a meeting when the number + # of audio participants reaches the specified threshold. + # Overrides any existing muteOnStart directive (bbb-web, API and the client). + # 0 = disabled. + muteOnStartThreshold = 0 + + # Whether guest policy should be enforced on dial-in endpoints + dialInEnforceGuestPolicy = true } recording { diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java index 076d82cc54..b136b0fd57 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/FreeswitchConferenceEventListener.java @@ -109,6 +109,7 @@ public class FreeswitchConferenceEventListener implements ConferenceEventListene evt.callSession, evt.clientSession, evt.userId, + evt.getVoiceUserId(), evt.callerName, evt.callState, evt.origCallerIdName, diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java index 5ca5f7b4c6..72080f8732 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/IVoiceConferenceService.java @@ -59,6 +59,7 @@ public interface IVoiceConferenceService { String callSession, String clientSession, String userId, + String voiceUserId, String callerName, String callState, String origCallerIdName, diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceCallStateEvent.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceCallStateEvent.java index 9d0a9277e6..f48b3576fd 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceCallStateEvent.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/events/VoiceCallStateEvent.java @@ -4,6 +4,8 @@ public class VoiceCallStateEvent extends VoiceConferenceEvent { public final String callSession; public final String clientSession; public final String userId; + // AKA mod_conference memberId + public final String voiceUserId; public final String callerName; public final String callState; public final String origCallerIdName; @@ -14,6 +16,7 @@ public class VoiceCallStateEvent extends VoiceConferenceEvent { String callSession, String clientSession, String userId, + String voiceUserId, String callerName, String callState, String origCallerIdName, @@ -22,9 +25,14 @@ public class VoiceCallStateEvent extends VoiceConferenceEvent { this.callSession = callSession; this.clientSession = clientSession; this.userId = userId; + this.voiceUserId = voiceUserId; this.callerName = callerName; this.callState = callState; this.origCallerIdName = origCallerIdName; this.origCalledDest = origCalledDest; } + + public String getVoiceUserId() { + return voiceUserId; + } } diff --git a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java index a67e6e5768..0549d6babf 100755 --- a/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java +++ b/akka-bbb-fsesl/src/main/java/org/bigbluebutton/freeswitch/voice/freeswitch/ESLEventListener.java @@ -84,6 +84,7 @@ public class ESLEventListener implements IEslEventListener { String origCallerIdName = headers.get("Caller-Caller-ID-Name"); String origCallerDestNumber = headers.get("Caller-Destination-Number"); String clientSession = "0"; + String memberIdStr = memberId != null ? memberId.toString() : ""; Matcher matcher = CALLERNAME_PATTERN.matcher(callerIdName); Matcher callWithSess = CALLERNAME_WITH_SESS_INFO_PATTERN.matcher(callerIdName); @@ -106,6 +107,7 @@ public class ESLEventListener implements IEslEventListener { coreuuid, clientSession, voiceUserId, + memberIdStr, callerIdName, callState, origCallerIdName, @@ -281,6 +283,7 @@ public class ESLEventListener implements IEslEventListener { String varvBridge = (eventHeaders.get("variable_vbridge") == null) ? "" : eventHeaders.get("variable_vbridge"); if ("echo".equalsIgnoreCase(application) && !varvBridge.isEmpty()) { + Integer memberId = this.getMemberId(eventHeaders); String origCallerIdName = eventHeaders.get("Caller-Caller-ID-Name"); String origCallerDestNumber = eventHeaders.get("Caller-Destination-Number"); String coreuuid = eventHeaders.get("Core-UUID"); @@ -291,6 +294,7 @@ public class ESLEventListener implements IEslEventListener { String callerName = origCallerIdName; String clientSession = "0"; String callState = "IN_ECHO_TEST"; + String memberIdStr = memberId != null ? memberId.toString() : ""; Matcher callerListenOnly = CALLERNAME_LISTENONLY_PATTERN.matcher(origCallerIdName); Matcher callWithSess = CALLERNAME_WITH_SESS_INFO_PATTERN.matcher(origCallerIdName); @@ -314,6 +318,7 @@ public class ESLEventListener implements IEslEventListener { coreuuid, clientSession, voiceUserId, + memberIdStr, callerName, callState, origCallerIdName, @@ -321,6 +326,7 @@ public class ESLEventListener implements IEslEventListener { conferenceEventListener.handleConferenceEvent(csEvent); } else if ("RINGING".equalsIgnoreCase(channelCallState) && !varvBridge.isEmpty()) { + Integer memberId = this.getMemberId(eventHeaders); String origCallerIdName = eventHeaders.get("Caller-Caller-ID-Name"); String origCallerDestNumber = eventHeaders.get("Caller-Destination-Number"); String coreuuid = eventHeaders.get("Core-UUID"); @@ -330,6 +336,7 @@ public class ESLEventListener implements IEslEventListener { String callerName = origCallerIdName; String clientSession = "0"; String callState = "CALL_STARTED"; + String memberIdStr = memberId != null ? memberId.toString() : ""; Matcher callerListenOnly = CALLERNAME_LISTENONLY_PATTERN.matcher(origCallerIdName); Matcher callWithSess = CALLERNAME_WITH_SESS_INFO_PATTERN.matcher(origCallerIdName); @@ -353,6 +360,7 @@ public class ESLEventListener implements IEslEventListener { coreuuid, clientSession, voiceUserId, + memberIdStr, callerName, callState, origCallerIdName, @@ -365,6 +373,7 @@ public class ESLEventListener implements IEslEventListener { String channelState = (eventHeaders.get("Channel-State") == null) ? "" : eventHeaders.get("Channel-State"); if ("HANGUP".equalsIgnoreCase(channelCallState) && "CS_DESTROY".equalsIgnoreCase(channelState)) { + Integer memberId = this.getMemberId(eventHeaders); String origCallerIdName = eventHeaders.get("Caller-Caller-ID-Name"); String origCallerDestNumber = eventHeaders.get("Caller-Destination-Number"); String coreuuid = eventHeaders.get("Core-UUID"); @@ -374,6 +383,7 @@ public class ESLEventListener implements IEslEventListener { String callerName = origCallerIdName; String clientSession = "0"; String callState = "CALL_ENDED"; + String memberIdStr = memberId != null ? memberId.toString() : ""; Matcher callerListenOnly = CALLERNAME_LISTENONLY_PATTERN.matcher(origCallerIdName); Matcher callWithSess = CALLERNAME_WITH_SESS_INFO_PATTERN.matcher(origCallerIdName); @@ -397,6 +407,7 @@ public class ESLEventListener implements IEslEventListener { coreuuid, clientSession, voiceUserId, + memberIdStr, callerName, callState, origCallerIdName, @@ -405,6 +416,7 @@ public class ESLEventListener implements IEslEventListener { conferenceEventListener.handleConferenceEvent(csEvent); } else if ("RINGING".equalsIgnoreCase(channelCallState) && "CS_EXECUTE".equalsIgnoreCase(channelState)) { + Integer memberId = this.getMemberId(eventHeaders); String origCallerIdName = eventHeaders.get("Caller-Caller-ID-Name"); String origCallerDestNumber = eventHeaders.get("Caller-Destination-Number"); String coreuuid = eventHeaders.get("Core-UUID"); @@ -414,6 +426,7 @@ public class ESLEventListener implements IEslEventListener { String callerName = origCallerIdName; String clientSession = "0"; String callState = "CALL_STARTED"; + String memberIdStr = memberId != null ? memberId.toString() : ""; Matcher callerListenOnly = CALLERNAME_LISTENONLY_PATTERN.matcher(origCallerIdName); Matcher callWithSess = CALLERNAME_WITH_SESS_INFO_PATTERN.matcher(origCallerIdName); @@ -437,6 +450,7 @@ public class ESLEventListener implements IEslEventListener { coreuuid, clientSession, voiceUserId, + memberIdStr, callerName, callState, origCallerIdName, diff --git a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala index 4e520a82dc..4c73bedcf5 100755 --- a/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala +++ b/akka-bbb-fsesl/src/main/scala/org/bigbluebutton/freeswitch/VoiceConferenceService.scala @@ -229,6 +229,7 @@ class VoiceConferenceService(healthz: HealthzService, callSession: String, clientSession: String, userId: String, + voiceUserId: String, callerName: String, callState: String, origCallerIdName: String, @@ -240,6 +241,7 @@ class VoiceConferenceService(healthz: HealthzService, callSession = callSession, clientSession = clientSession, userId = userId, + voiceUserId = voiceUserId, callerName = callerName, callState = callState, origCallerIdName = origCallerIdName, diff --git a/bbb-common-message/deploy.sh b/bbb-common-message/deploy.sh index bab0c8b2aa..e374b88709 100755 --- a/bbb-common-message/deploy.sh +++ b/bbb-common-message/deploy.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e #Publish new common-message .jar sbt clean diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala index a30922bce3..2e2c9dd904 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Meeting2x.scala @@ -36,7 +36,7 @@ case class PasswordProp(moderatorPass: String, viewerPass: String, learningDashb case class RecordProp(record: Boolean, autoStartRecording: Boolean, allowStartStopRecording: Boolean, recordFullDurationMedia: Boolean, keepEvents: Boolean) -case class WelcomeProp(welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMessage: String) +case class WelcomeProp(welcomeMsg: String, welcomeMsgForModerators: String) case class VoiceProp(telVoice: String, voiceConf: String, dialNumber: String, muteOnStart: Boolean) @@ -50,7 +50,8 @@ case class UsersProp( allowModsToUnmuteUsers: Boolean, allowModsToEjectCameras: Boolean, authenticatedGuest: Boolean, - allowPromoteGuestToModerator: Boolean + allowPromoteGuestToModerator: Boolean, + waitingGuestUsersTimeout: Long ) case class MetadataProp(metadata: collection.immutable.Map[String, String]) @@ -72,6 +73,7 @@ case class SystemProps( loginUrl: String, logoutUrl: String, customLogoURL: String, + customDarkLogoURL: String, bannerText: String, bannerColor: String, ) @@ -120,8 +122,8 @@ case class UserVO(id: String, externalId: String, name: String, role: String, guest: Boolean, authed: Boolean, guestStatus: String, emojiStatus: String, presenter: Boolean, hasStream: Boolean, locked: Boolean, webcamStreams: Set[String], phoneUser: Boolean, voiceUser: VoiceUserVO, listenOnly: Boolean, avatarURL: String, - joinedWeb: Boolean) + webcamBackgroundURL: String, joinedWeb: Boolean) case class VoiceUserVO(userId: String, webUserId: String, callerName: String, callerNum: String, joined: Boolean, locked: Boolean, muted: Boolean, - talking: Boolean, avatarURL: String, listenOnly: Boolean) + talking: Boolean, avatarURL: String, webcamBackgroundURL: String, listenOnly: Boolean) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Plugins.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Plugins.scala new file mode 100644 index 0000000000..9e098c023d --- /dev/null +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/domain/Plugins.scala @@ -0,0 +1,7 @@ +package org.bigbluebutton.common2.domain + +case class PluginLearningAnalyticsDashboardGenericData( + columnTitle: String, + cardTitle: String, + value: String, + ) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/BreakoutMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/BreakoutMsgs.scala index 7ac03144e3..1783e4cbc3 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/BreakoutMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/BreakoutMsgs.scala @@ -26,13 +26,6 @@ object BreakoutRoomStartedEvtMsg { val NAME = "BreakoutRoomStartedEvtMsg" } case class BreakoutRoomStartedEvtMsg(header: BbbClientMsgHeader, body: BreakoutRoomStartedEvtMsgBody) extends BbbCoreMsg case class BreakoutRoomStartedEvtMsgBody(parentMeetingId: String, breakout: BreakoutRoomInfo) -object BreakoutRoomsTimeRemainingUpdateEvtMsg { val NAME = "BreakoutRoomsTimeRemainingUpdateEvtMsg" } -case class BreakoutRoomsTimeRemainingUpdateEvtMsg( - header: BbbClientMsgHeader, - body: BreakoutRoomsTimeRemainingUpdateEvtMsgBody -) extends BbbCoreMsg -case class BreakoutRoomsTimeRemainingUpdateEvtMsgBody(timeRemaining: Long) - /** * Sent to bbb-web to create breakout rooms. */ @@ -71,7 +64,7 @@ case class BreakoutRoomDetail( object CreateBreakoutRoomsCmdMsg { val NAME = "CreateBreakoutRoomsCmdMsg" } case class CreateBreakoutRoomsCmdMsg(header: BbbClientMsgHeader, body: CreateBreakoutRoomsCmdMsgBody) extends StandardMsg case class CreateBreakoutRoomsCmdMsgBody(meetingId: String, durationInMinutes: Int, record: Boolean, captureNotes: Boolean, captureSlides: Boolean, rooms: Vector[BreakoutRoomMsgBody], sendInviteToModerators: Boolean) -case class BreakoutRoomMsgBody(name: String, sequence: Int, shortName: String, captureNotesFilename: String, captureSlidesFilename: String, isDefaultName: Boolean, freeJoin: Boolean, users: Vector[String]) +case class BreakoutRoomMsgBody(name: String, sequence: Int, shortName: String, captureNotesFilename: String, captureSlidesFilename: String, isDefaultName: Boolean, freeJoin: Boolean, users: Vector[String], allPages: Boolean, presId: String) // Sent by user to request ending all the breakout rooms object EndAllBreakoutRoomsMsg { val NAME = "EndAllBreakoutRoomsMsg" } @@ -85,6 +78,10 @@ object RequestBreakoutJoinURLReqMsg { val NAME = "RequestBreakoutJoinURLReqMsg" case class RequestBreakoutJoinURLReqMsg(header: BbbClientMsgHeader, body: RequestBreakoutJoinURLReqMsgBody) extends StandardMsg case class RequestBreakoutJoinURLReqMsgBody(meetingId: String, breakoutId: String, userId: String) +object SetBreakoutRoomInviteDismissedReqMsg { val NAME = "SetBreakoutRoomInviteDismissedReqMsg" } +case class SetBreakoutRoomInviteDismissedReqMsg(header: BbbClientMsgHeader, body: SetBreakoutRoomInviteDismissedReqMsgBody) extends StandardMsg +case class SetBreakoutRoomInviteDismissedReqMsgBody() + object TransferUserToMeetingEvtMsg { val NAME = "TransferUserToMeetingEvtMsg" } case class TransferUserToMeetingEvtMsg(header: BbbClientMsgHeader, body: TransferUserToMeetingEvtMsgBody) extends BbbCoreMsg case class TransferUserToMeetingEvtMsgBody(fromVoiceConf: String, toVoiceConf: String, userId: String) @@ -94,10 +91,6 @@ object TransferUserToMeetingRequestMsg { val NAME = "TransferUserToMeetingReques case class TransferUserToMeetingRequestMsg(header: BbbClientMsgHeader, body: TransferUserToMeetingRequestMsgBody) extends StandardMsg case class TransferUserToMeetingRequestMsgBody(fromMeetingId: String, toMeetingId: String, userId: String) -object UpdateBreakoutUsersEvtMsg { val NAME = "UpdateBreakoutUsersEvtMsg" } -case class UpdateBreakoutUsersEvtMsg(header: BbbClientMsgHeader, body: UpdateBreakoutUsersEvtMsgBody) extends BbbCoreMsg -case class UpdateBreakoutUsersEvtMsgBody(parentId: String, breakoutId: String, users: Vector[BreakoutUserVO]) - object UpdateBreakoutRoomsTimeReqMsg { val NAME = "UpdateBreakoutRoomsTimeReqMsg" } case class UpdateBreakoutRoomsTimeReqMsg(header: BbbClientMsgHeader, body: UpdateBreakoutRoomsTimeReqMsgBody) extends StandardMsg case class UpdateBreakoutRoomsTimeReqMsgBody(meetingId: String, timeInMinutes: Int) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/CaptionMessages.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/CaptionMessages.scala index ad83dac43a..ef51e09847 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/CaptionMessages.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/CaptionMessages.scala @@ -5,10 +5,26 @@ object EditCaptionHistoryPubMsg { val NAME = "EditCaptionHistoryPubMsg" } case class EditCaptionHistoryPubMsg(header: BbbClientMsgHeader, body: EditCaptionHistoryPubMsgBody) extends StandardMsg case class EditCaptionHistoryPubMsgBody(startIndex: Integer, endIndex: Integer, name: String, locale: String, text: String) -object UpdateCaptionOwnerPubMsg { val NAME = "UpdateCaptionOwnerPubMsg" } -case class UpdateCaptionOwnerPubMsg(header: BbbClientMsgHeader, body: UpdateCaptionOwnerPubMsgBody) extends StandardMsg -case class UpdateCaptionOwnerPubMsgBody(name: String, locale: String, ownerId: String) +object AddCaptionLocalePubMsg { val NAME = "AddCaptionLocalePubMsg" } +case class AddCaptionLocalePubMsg(header: BbbClientMsgHeader, body: AddCaptionLocalePubMsgBody) extends StandardMsg +case class AddCaptionLocalePubMsgBody(locale: String) +object CaptionSubmitTranscriptPubMsg { val NAME = "CaptionSubmitTranscriptPubMsg" } +case class CaptionSubmitTranscriptPubMsg(header: BbbClientMsgHeader, body: CaptionSubmitTranscriptPubMsgBody) extends StandardMsg +case class CaptionSubmitTranscriptPubMsgBody( + transcriptId: String, + transcript: String, + locale: String, + captionType: String, + ) +object CaptionSubmitTranscriptEvtMsg { val NAME = "CaptionSubmitTranscriptEvtMsg" } +case class CaptionSubmitTranscriptEvtMsg(header: BbbClientMsgHeader, body: CaptionSubmitTranscriptEvtMsgBody) extends StandardMsg +case class CaptionSubmitTranscriptEvtMsgBody( + transcriptId: String, + transcript: String, + locale: String, + captionType: String, + ) object SendCaptionHistoryReqMsg { val NAME = "SendCaptionHistoryReqMsg" } case class SendCaptionHistoryReqMsg(header: BbbClientMsgHeader, body: SendCaptionHistoryReqMsgBody) extends StandardMsg case class SendCaptionHistoryReqMsgBody() @@ -18,9 +34,9 @@ object EditCaptionHistoryEvtMsg { val NAME = "EditCaptionHistoryEvtMsg" } case class EditCaptionHistoryEvtMsg(header: BbbClientMsgHeader, body: EditCaptionHistoryEvtMsgBody) extends StandardMsg case class EditCaptionHistoryEvtMsgBody(startIndex: Integer, endIndex: Integer, name: String, locale: String, text: String) -object UpdateCaptionOwnerEvtMsg { val NAME = "UpdateCaptionOwnerEvtMsg" } -case class UpdateCaptionOwnerEvtMsg(header: BbbClientMsgHeader, body: UpdateCaptionOwnerEvtMsgBody) extends StandardMsg -case class UpdateCaptionOwnerEvtMsgBody(name: String, locale: String, ownerId: String) +object AddCaptionLocaleEvtMsg { val NAME = "AddCaptionLocaleEvtMsg" } +case class AddCaptionLocaleEvtMsg(header: BbbClientMsgHeader, body: AddCaptionLocaleEvtMsgBody) extends StandardMsg +case class AddCaptionLocaleEvtMsgBody(locale: String) object SendCaptionHistoryRespMsg { val NAME = "SendCaptionHistoryRespMsg" } case class SendCaptionHistoryRespMsg(header: BbbClientMsgHeader, body: SendCaptionHistoryRespMsgBody) extends StandardMsg diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/GroupChatMsg.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/GroupChatMsg.scala index 1ce64fad17..131cbb8180 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/GroupChatMsg.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/GroupChatMsg.scala @@ -7,15 +7,17 @@ object GroupChatAccess { object GroupChatMessageType { val DEFAULT = "default" + val API = "api" val PRESENTATION = "presentation" val POLL = "poll" val BREAKOUTROOM_MOD_MSG = "breakoutRoomModeratorMsg" val PUBLIC_CHAT_HIST_CLEARED = "publicChatHistoryCleared" val USER_AWAY_STATUS_MSG = "userAwayStatusMsg" + val PLUGIN = "plugin" } case class GroupChatUser(id: String, name: String = "", role: String = "VIEWER") -case class GroupChatMsgFromUser(correlationId: String, sender: GroupChatUser, message: String) +case class GroupChatMsgFromUser(correlationId: String, sender: GroupChatUser, message: String, metadata: Map[String, Any] = Map.empty) case class GroupChatMsgToUser(id: String, timestamp: Long, correlationId: String, sender: GroupChatUser, chatEmphasizedText: Boolean = false, message: String) case class GroupChatInfo(id: String, access: String, createdBy: GroupChatUser, users: Vector[GroupChatUser]) @@ -90,6 +92,16 @@ object SendGroupChatMessageMsg { val NAME = "SendGroupChatMessageMsg" } case class SendGroupChatMessageMsg(header: BbbClientMsgHeader, body: SendGroupChatMessageMsgBody) extends StandardMsg case class SendGroupChatMessageMsgBody(chatId: String, msg: GroupChatMsgFromUser) +object SendGroupChatMessageFromApiSysPubMsg { val NAME = "SendGroupChatMessageFromApiSysPubMsg" } +case class SendGroupChatMessageFromApiSysPubMsg( + header: BbbClientMsgHeader, + body: SendGroupChatMessageFromApiSysPubMsgBody +) extends StandardMsg +case class SendGroupChatMessageFromApiSysPubMsgBody( + userName: String, + message: String +) + object GroupChatMessageBroadcastEvtMsg { val NAME = "GroupChatMessageBroadcastEvtMsg" } case class GroupChatMessageBroadcastEvtMsg(header: BbbClientMsgHeader, body: GroupChatMessageBroadcastEvtMsgBody) extends BbbCoreMsg case class GroupChatMessageBroadcastEvtMsgBody(chatId: String, msg: GroupChatMsgToUser) @@ -98,11 +110,10 @@ object UserTypingPubMsg { val NAME = "UserTypingPubMsg" } case class UserTypingPubMsg(header: BbbClientMsgHeader, body: UserTypingPubMsgBody) extends StandardMsg case class UserTypingPubMsgBody(chatId: String) -// html5 client only -object SyncGetGroupChatsRespMsg { val NAME = "SyncGetGroupChatsRespMsg" } -case class SyncGetGroupChatsRespMsg(header: BbbClientMsgHeader, body: SyncGetGroupChatsRespMsgBody) extends BbbCoreMsg -case class SyncGetGroupChatsRespMsgBody(chats: Vector[GroupChatInfo]) +object SetGroupChatVisibleReqMsg { val NAME = "SetGroupChatVisibleReqMsg" } +case class SetGroupChatVisibleReqMsg(header: BbbClientMsgHeader, body: SetGroupChatVisibleReqMsgBody) extends StandardMsg +case class SetGroupChatVisibleReqMsgBody(chatId: String, visible: Boolean) -object SyncGetGroupChatMsgsRespMsg { val NAME = "SyncGetGroupChatMsgsRespMsg" } -case class SyncGetGroupChatMsgsRespMsg(header: BbbClientMsgHeader, body: SyncGetGroupChatMsgsRespMsgBody) extends BbbCoreMsg -case class SyncGetGroupChatMsgsRespMsgBody(chatId: String, msgs: Vector[GroupChatMsgToUser]) +object SetGroupChatLastSeenReqMsg { val NAME = "SetGroupChatLastSeenReqMsg" } +case class SetGroupChatLastSeenReqMsg(header: BbbClientMsgHeader, body: SetGroupChatLastSeenReqMsgBody) extends StandardMsg +case class SetGroupChatLastSeenReqMsgBody(chatId: String, lastSeenAt: String) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/GuestsMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/GuestsMsgs.scala index ba98c73be1..4d8bc314e2 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/GuestsMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/GuestsMsgs.scala @@ -63,16 +63,6 @@ case class GuestApprovedEvtMsg( ) extends BbbCoreMsg case class GuestApprovedEvtMsgBody(status: String, approvedBy: String) -/** - * Message from bbb-web when it detects a guest stopped polling for his status. - */ -object GuestWaitingLeftMsg { val NAME = "GuestWaitingLeftMsg" } -case class GuestWaitingLeftMsg( - header: BbbClientMsgHeader, - body: GuestWaitingLeftMsgBody -) extends StandardMsg -case class GuestWaitingLeftMsgBody(userId: String) - /** * Message sent to all clients that a guest left the waiting page. */ diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PadsMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PadsMsgs.scala index fad8a926a1..2ad0240c5e 100644 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PadsMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PadsMsgs.scala @@ -4,11 +4,6 @@ trait PadStandardMsg extends BbbCoreMsg { def header: BbbCoreHeaderWithMeetingId } -// client -> apps -object PadCreateGroupReqMsg { val NAME = "PadCreateGroupReqMsg" } -case class PadCreateGroupReqMsg(header: BbbClientMsgHeader, body: PadCreateGroupReqMsgBody) extends StandardMsg -case class PadCreateGroupReqMsgBody(externalId: String, model: String, name: String) - // apps -> pads object PadCreateGroupCmdMsg { val NAME = "PadCreateGroupCmdMsg" } case class PadCreateGroupCmdMsg(header: BbbCoreHeaderWithMeetingId, body: PadCreateGroupCmdMsgBody) extends BbbCoreMsg diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PluginMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PluginMsgs.scala index ec6ca3bda7..7fe61c9d8b 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PluginMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PluginMsgs.scala @@ -1,5 +1,7 @@ package org.bigbluebutton.common2.msgs +import org.bigbluebutton.common2.domain.PluginLearningAnalyticsDashboardGenericData + // In messages /** @@ -11,25 +13,42 @@ case class PluginDataChannelPushEntryMsgBody( pluginName: String, channelName: String, subChannelName: String, - payloadJson: String, + payloadJson: Map[String, Any], toRoles: List[String], toUserIds: List[String], ) +object PluginDataChannelReplaceEntryMsg { val NAME = "PluginDataChannelReplaceEntryMsg" } +case class PluginDataChannelReplaceEntryMsg(header: BbbClientMsgHeader, body: PluginDataChannelReplaceEntryMsgBody) extends StandardMsg +case class PluginDataChannelReplaceEntryMsgBody( + pluginName: String, + channelName: String, + subChannelName: String, + payloadJson: Map[String, Any], + entryId: String, + ) + object PluginDataChannelDeleteEntryMsg { val NAME = "PluginDataChannelDeleteEntryMsg" } case class PluginDataChannelDeleteEntryMsg(header: BbbClientMsgHeader, body: PluginDataChannelDeleteEntryMsgBody) extends StandardMsg case class PluginDataChannelDeleteEntryMsgBody( - pluginName: String, - subChannelName: String, - channelName: String, - entryId: String - ) + pluginName: String, + subChannelName: String, + channelName: String, + entryId: String + ) object PluginDataChannelResetMsg { val NAME = "PluginDataChannelResetMsg" } case class PluginDataChannelResetMsg(header: BbbClientMsgHeader, body: PluginDataChannelResetMsgBody) extends StandardMsg case class PluginDataChannelResetMsgBody( - pluginName: String, - subChannelName: String, - channelName: String - ) + pluginName: String, + subChannelName: String, + channelName: String + ) + +object PluginLearningAnalyticsDashboardSendGenericDataMsg { val NAME = "PluginLearningAnalyticsDashboardSendGenericDataMsg" } +case class PluginLearningAnalyticsDashboardSendGenericDataMsg(header: BbbClientMsgHeader, body: PluginLearningAnalyticsDashboardSendGenericDataMsgBody) extends StandardMsg +case class PluginLearningAnalyticsDashboardSendGenericDataMsgBody( + pluginName: String, + genericDataForLearningAnalyticsDashboard: PluginLearningAnalyticsDashboardGenericData + ) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationPodsMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationPodsMsgs.scala index c2b72804d1..d5e22eda9e 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationPodsMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/PresentationPodsMsgs.scala @@ -23,6 +23,10 @@ object SetCurrentPagePubMsg { val NAME = "SetCurrentPagePubMsg" } case class SetCurrentPagePubMsg(header: BbbClientMsgHeader, body: SetCurrentPagePubMsgBody) extends StandardMsg case class SetCurrentPagePubMsgBody(podId: String, presentationId: String, pageId: String) +object SetPageInfiniteWhiteboardPubMsg { val NAME = "SetPageInfiniteWhiteboardPubMsg" } +case class SetPageInfiniteWhiteboardPubMsg(header: BbbClientMsgHeader, body: SetPageInfiniteWhiteboardPubMsgBody) extends StandardMsg +case class SetPageInfiniteWhiteboardPubMsgBody(pageId: String, infiniteWhiteboard: Boolean) + object RemovePresentationPubMsg { val NAME = "RemovePresentationPubMsg" } case class RemovePresentationPubMsg(header: BbbClientMsgHeader, body: RemovePresentationPubMsgBody) extends StandardMsg case class RemovePresentationPubMsgBody(podId: String, presentationId: String) @@ -325,6 +329,10 @@ object SetCurrentPageEvtMsg { val NAME = "SetCurrentPageEvtMsg" } case class SetCurrentPageEvtMsg(header: BbbClientMsgHeader, body: SetCurrentPageEvtMsgBody) extends BbbCoreMsg case class SetCurrentPageEvtMsgBody(podId: String, presentationId: String, pageId: String) +object SetPageInfiniteWhiteboardEvtMsg { val NAME = "SetPageInfiniteWhiteboardEvtMsg" } +case class SetPageInfiniteWhiteboardEvtMsg(header: BbbClientMsgHeader, body: SetPageInfiniteWhiteboardEvtMsgBody) extends BbbCoreMsg +case class SetPageInfiniteWhiteboardEvtMsgBody(pageId: String, infiniteWhiteboard: Boolean) + object SetPresenterInPodRespMsg { val NAME = "SetPresenterInPodRespMsg" } case class SetPresenterInPodRespMsg(header: BbbClientMsgHeader, body: SetPresenterInPodRespMsgBody) extends StandardMsg case class SetPresenterInPodRespMsgBody(podId: String, nextPresenterId: String) @@ -347,11 +355,6 @@ object SetCurrentPresentationEvtMsg { val NAME = "SetCurrentPresentationEvtMsg" case class SetCurrentPresentationEvtMsg(header: BbbClientMsgHeader, body: SetCurrentPresentationEvtMsgBody) extends BbbCoreMsg case class SetCurrentPresentationEvtMsgBody(podId: String, presentationId: String) -// html5 client only -object SyncGetPresentationPodsRespMsg { val NAME = "SyncGetPresentationPodsRespMsg" } -case class SyncGetPresentationPodsRespMsg(header: BbbClientMsgHeader, body: SyncGetPresentationPodsRespMsgBody) extends BbbCoreMsg -case class SyncGetPresentationPodsRespMsgBody(pods: Vector[PresentationPodVO]) - // ------------ akka-apps to client ------------ // ------------ akka-apps to bbb-common-web ------------ diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala index ca2970c916..d72ada0503 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala @@ -30,34 +30,6 @@ case class EndMeetingSysCmdMsg( ) extends StandardMsg case class EndMeetingSysCmdMsgBody(meetingId: String) -object GetAllMeetingsReqMsg { val NAME = "GetAllMeetingsReqMsg" } -case class GetAllMeetingsReqMsg( - header: BbbCoreBaseHeader, - body: GetAllMeetingsReqMsgBody -) extends BbbCoreMsg -case class GetAllMeetingsReqMsgBody(requesterId: String) - -object GetRunningMeetingsReqMsg { val NAME = "GetRunningMeetingsReqMsg" } -case class GetRunningMeetingsReqMsg( - header: BbbCoreBaseHeader, - body: GetRunningMeetingsReqMsgBody -) extends BbbCoreMsg -case class GetRunningMeetingsReqMsgBody(requesterId: String) - -object GetRunningMeetingsRespMsg { val NAME = "GetRunningMeetingsRespMsg" } -case class GetRunningMeetingsRespMsg( - header: BbbCoreBaseHeader, - body: GetRunningMeetingsRespMsgBody -) extends BbbCoreMsg -case class GetRunningMeetingsRespMsgBody(meetings: Vector[String]) - -object GetRunningMeetingStateReqMsg { val NAME = "GetRunningMeetingStateReqMsg" } -case class GetRunningMeetingStateReqMsg( - header: BbbCoreBaseHeader, - body: GetRunningMeetingStateReqMsgBody -) extends BbbCoreMsg -case class GetRunningMeetingStateReqMsgBody(meetingId: String) - object PubSubPingSysReqMsg { val NAME = "PubSubPingSysReqMsg" } case class PubSubPingSysReqMsg( header: BbbCoreBaseHeader, @@ -141,20 +113,6 @@ case class DisconnectAllClientsSysMsg( ) extends BbbCoreMsg case class DisconnectAllClientsSysMsgBody(meetingId: String, reason: String) -object DisconnectClientSysMsg { val NAME = "DisconnectClientSysMsg" } -case class DisconnectClientSysMsg( - header: BbbCoreHeaderWithMeetingId, - body: DisconnectClientSysMsgBody -) extends BbbCoreMsg -case class DisconnectClientSysMsgBody(meetingId: String, userId: String, ejectedBy: String, reason: String) - -object EndAndKickAllSysMsg { val NAME = "EndAndKickAllSysMsg" } -case class EndAndKickAllSysMsg( - header: BbbCoreHeaderWithMeetingId, - body: EndAndKickAllSysMsgBody -) extends BbbCoreMsg -case class EndAndKickAllSysMsgBody(meetingId: String) - object RecordStatusResetSysMsg { val NAME = "RecordStatusResetSysMsg" } case class RecordStatusResetSysMsg( header: BbbCoreHeaderWithMeetingId, @@ -162,13 +120,6 @@ case class RecordStatusResetSysMsg( ) extends BbbCoreMsg case class RecordStatusResetSysMsgBody(recording: Boolean, setBy: String) -object SyncGetMeetingInfoRespMsg { val NAME = "SyncGetMeetingInfoRespMsg" } -case class SyncGetMeetingInfoRespMsg( - header: BbbCoreBaseHeader, - body: SyncGetMeetingInfoRespMsgBody -) extends BbbCoreMsg -case class SyncGetMeetingInfoRespMsgBody(props: DefaultProps) - object PubSubPongSysRespMsg { val NAME = "PubSubPongSysRespMsg" } case class PubSubPongSysRespMsg( header: BbbCoreBaseHeader, @@ -176,13 +127,6 @@ case class PubSubPongSysRespMsg( ) extends BbbCoreMsg case class PubSubPongSysRespMsgBody(system: String, timestamp: Long) -object MeetingTimeRemainingUpdateEvtMsg { val NAME = "MeetingTimeRemainingUpdateEvtMsg" } -case class MeetingTimeRemainingUpdateEvtMsg( - header: BbbClientMsgHeader, - body: MeetingTimeRemainingUpdateEvtMsgBody -) extends BbbCoreMsg -case class MeetingTimeRemainingUpdateEvtMsgBody(timeLeftInSec: Long, timeUpdatedInMinutes: Int) - object CheckAlivePingSysMsg { val NAME = "CheckAlivePingSysMsg" } case class CheckAlivePingSysMsg( header: BbbCoreBaseHeader, @@ -204,22 +148,6 @@ case class RecordingChapterBreakSysMsg( ) extends BbbCoreMsg case class RecordingChapterBreakSysMsgBody(meetingId: String, timestamp: Long) -object ValidateConnAuthTokenSysMsg { val NAME = "ValidateConnAuthTokenSysMsg" } -case class ValidateConnAuthTokenSysMsg( - header: BbbCoreBaseHeader, - body: ValidateConnAuthTokenSysMsgBody -) extends BbbCoreMsg -case class ValidateConnAuthTokenSysMsgBody(meetingId: String, userId: String, authToken: String, - connId: String, app: String) - -object ValidateConnAuthTokenSysRespMsg { val NAME = "ValidateConnAuthTokenSysRespMsg" } -case class ValidateConnAuthTokenSysRespMsg( - header: BbbCoreHeaderWithMeetingId, - body: ValidateConnAuthTokenSysRespMsgBody -) extends BbbCoreMsg -case class ValidateConnAuthTokenSysRespMsgBody(meetingId: String, userId: String, - connId: String, authzed: Boolean, app: String) - object PublishedRecordingSysMsg { val NAME = "PublishedRecordingSysMsg" } case class PublishedRecordingSysMsg(header: BbbCoreBaseHeader, body: PublishedRecordingSysMsgBody) extends BbbCoreMsg case class PublishedRecordingSysMsgBody(recordId: String) @@ -278,7 +206,14 @@ case class UserGraphqlConnectionEstablishedSysMsg( header: BbbCoreBaseHeader, body: UserGraphqlConnectionEstablishedSysMsgBody ) extends BbbCoreMsg -case class UserGraphqlConnectionEstablishedSysMsgBody(middlewareUID: String, sessionToken: String, browserConnectionId: String) +case class UserGraphqlConnectionEstablishedSysMsgBody( + middlewareUID: String, + sessionToken: String, + clientSessionUUID: String, + clientType: String, + clientIsMobile: Boolean, + browserConnectionId: String +) object UserGraphqlConnectionClosedSysMsg { val NAME = "UserGraphqlConnectionClosedSysMsg" } case class UserGraphqlConnectionClosedSysMsg( diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/TimerMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/TimerMsgs.scala index 34ebca4159..a3ba3fe3d5 100644 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/TimerMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/TimerMsgs.scala @@ -1,10 +1,6 @@ package org.bigbluebutton.common2.msgs /* In Messages */ -object CreateTimerPubMsg { val NAME = "CreateTimerPubMsg" } -case class CreateTimerPubMsg(header: BbbClientMsgHeader, body: CreateTimerPubMsgBody) extends StandardMsg -case class CreateTimerPubMsgBody(stopwatch: Boolean, running: Boolean, time: Int, accumulated: Int, timestamp: Int, track: String) - object ActivateTimerReqMsg { val NAME = "ActivateTimerReqMsg" } case class ActivateTimerReqMsg(header: BbbClientMsgHeader, body: ActivateTimerReqMsgBody) extends StandardMsg case class ActivateTimerReqMsgBody(stopwatch: Boolean, running: Boolean, time: Int, accumulated: Int, timestamp: Int, track: String) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMsgs.scala index 13cabc554a..352e513a0f 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMsgs.scala @@ -7,8 +7,8 @@ case class RegisterUserReqMsg( ) extends BbbCoreMsg case class RegisterUserReqMsgBody(meetingId: String, intUserId: String, name: String, role: String, extUserId: String, authToken: String, sessionToken: String, avatarURL: String, - guest: Boolean, authed: Boolean, guestStatus: String, excludeFromDashboard: Boolean, - enforceLayout: String, customParameters: Map[String, String]) + webcamBackgroundURL: String, guest: Boolean, authed: Boolean, guestStatus: String, + excludeFromDashboard: Boolean, enforceLayout: String, userMetadata: Map[String, String]) object UserRegisteredRespMsg { val NAME = "UserRegisteredRespMsg" } case class UserRegisteredRespMsg( @@ -18,37 +18,10 @@ case class UserRegisteredRespMsg( case class UserRegisteredRespMsgBody(meetingId: String, userId: String, name: String, role: String, excludeFromDashboard: Boolean, registeredOn: Long) -object ValidateAuthTokenReqMsg { - val NAME = "ValidateAuthTokenReqMsg" - - def apply(meetingId: String, userId: String, authToken: String): ValidateAuthTokenReqMsg = { - val header = BbbClientMsgHeader(ValidateAuthTokenReqMsg.NAME, meetingId, userId) - - val body = ValidateAuthTokenReqMsgBody(userId, authToken) - ValidateAuthTokenReqMsg(header, body) - } -} - -case class ValidateAuthTokenReqMsg( - header: BbbClientMsgHeader, - body: ValidateAuthTokenReqMsgBody -) extends StandardMsg -case class ValidateAuthTokenReqMsgBody(userId: String, authToken: String) - /** * Out Messages */ -object ValidateAuthTokenRespMsg { - val NAME = "ValidateAuthTokenRespMsg" -} -case class ValidateAuthTokenRespMsg( - header: BbbClientMsgHeader, - body: ValidateAuthTokenRespMsgBody -) extends BbbCoreMsg -case class ValidateAuthTokenRespMsgBody(userId: String, authToken: String, valid: Boolean, waitForApproval: Boolean, - registeredOn: Long, authTokenValidatedOn: Long, reasonCode: String, reason: String) - object UserLeftMeetingEvtMsg { val NAME = "UserLeftMeetingEvtMsg" def apply(meetingId: String, userId: String, body: UserLeftMeetingEvtMsgBody): UserLeftMeetingEvtMsg = { @@ -90,23 +63,24 @@ case class UserJoinedMeetingEvtMsg( body: UserJoinedMeetingEvtMsgBody ) extends BbbCoreMsg case class UserJoinedMeetingEvtMsgBody( - intId: String, - extId: String, - name: String, - role: String, - guest: Boolean, - authed: Boolean, - guestStatus: String, - emoji: String, - reactionEmoji: String, - raiseHand: Boolean, - away: Boolean, - pin: Boolean, - presenter: Boolean, - locked: Boolean, - avatar: String, - color: String, - clientType: String + intId: String, + extId: String, + name: String, + role: String, + guest: Boolean, + authed: Boolean, + guestStatus: String, + reactionEmoji: String, + raiseHand: Boolean, + away: Boolean, + pin: Boolean, + presenter: Boolean, + locked: Boolean, + avatar: String, + webcamBackground: String, + color: String, + clientType: String, + userMetadata: Map[String, String] ) /** @@ -156,10 +130,6 @@ object RecordingStatusChangedEvtMsg { val NAME = "RecordingStatusChangedEvtMsg" case class RecordingStatusChangedEvtMsg(header: BbbClientMsgHeader, body: RecordingStatusChangedEvtMsgBody) extends BbbCoreMsg case class RecordingStatusChangedEvtMsgBody(recording: Boolean, setBy: String) -object UpdateRecordingTimerEvtMsg { val NAME = "UpdateRecordingTimerEvtMsg" } -case class UpdateRecordingTimerEvtMsg(header: BbbClientMsgHeader, body: UpdateRecordingTimerEvtMsgBody) extends BbbCoreMsg -case class UpdateRecordingTimerEvtMsgBody(time: Long) - /** * Sent by user to update webcamsOnlyForModerator meeting property. */ @@ -195,20 +165,6 @@ object GetScreenshareStatusReqMsg { val NAME = "GetScreenshareStatusReqMsg" } case class GetScreenshareStatusReqMsg(header: BbbClientMsgHeader, body: GetScreenshareStatusReqMsgBody) extends StandardMsg case class GetScreenshareStatusReqMsgBody(requestedBy: String) -/** - * Sent from client about a user changing emoji. - */ -object ChangeUserEmojiCmdMsg { val NAME = "ChangeUserEmojiCmdMsg" } -case class ChangeUserEmojiCmdMsg(header: BbbClientMsgHeader, body: ChangeUserEmojiCmdMsgBody) extends StandardMsg -case class ChangeUserEmojiCmdMsgBody(userId: String, emoji: String) - -/** - * Sent to all clients about a user changing emoji. - */ -object UserEmojiChangedEvtMsg { val NAME = "UserEmojiChangedEvtMsg" } -case class UserEmojiChangedEvtMsg(header: BbbClientMsgHeader, body: UserEmojiChangedEvtMsgBody) extends BbbCoreMsg -case class UserEmojiChangedEvtMsgBody(userId: String, emoji: String) - /** * Sent from client about a user changing RaiseHand. */ @@ -251,27 +207,6 @@ object UserReactionEmojiChangedEvtMsg { val NAME = "UserReactionEmojiChangedEvtM case class UserReactionEmojiChangedEvtMsg(header: BbbClientMsgHeader, body: UserReactionEmojiChangedEvtMsgBody) extends BbbCoreMsg case class UserReactionEmojiChangedEvtMsgBody(userId: String, reactionEmoji: String) -/** - * Sent from meteor about a user reaction's expiration. - */ -object UserReactionTimeExpiredCmdMsg { val NAME = "UserReactionTimeExpiredCmdMsg" } -case class UserReactionTimeExpiredCmdMsg(header: BbbClientMsgHeader, body: UserReactionTimeExpiredCmdMsgBody) extends StandardMsg -case class UserReactionTimeExpiredCmdMsgBody(userId: String) - -/** - * Sent from client about a mod clearing all users' emoji. - */ -object ClearAllUsersEmojiCmdMsg { val NAME = "ClearAllUsersEmojiCmdMsg" } -case class ClearAllUsersEmojiCmdMsg(header: BbbClientMsgHeader, body: ClearAllUsersEmojiCmdMsgBody) extends StandardMsg -case class ClearAllUsersEmojiCmdMsgBody(userId: String) - -/** - * Sent to all clients about clearing all users' emoji. - */ -object ClearedAllUsersEmojiEvtMsg { val NAME = "ClearedAllUsersEmojiEvtMsg" } -case class ClearedAllUsersEmojiEvtMsg(header: BbbClientMsgHeader, body: ClearedAllUsersEmojiEvtMsgBody) extends StandardMsg -case class ClearedAllUsersEmojiEvtMsgBody() - /** * Sent from client about a mod clearing all users' Reaction. */ @@ -286,13 +221,6 @@ object ClearedAllUsersReactionEvtMsg { val NAME = "ClearedAllUsersReactionEvtMsg case class ClearedAllUsersReactionEvtMsg(header: BbbClientMsgHeader, body: ClearedAllUsersReactionEvtMsgBody) extends StandardMsg case class ClearedAllUsersReactionEvtMsgBody() -/** - * Sent from client about a user mobile flag. - */ -object ChangeUserMobileFlagReqMsg { val NAME = "ChangeUserMobileFlagReqMsg" } -case class ChangeUserMobileFlagReqMsg(header: BbbClientMsgHeader, body: ChangeUserMobileFlagReqMsgBody) extends StandardMsg -case class ChangeUserMobileFlagReqMsgBody(userId: String, mobile: Boolean) - /** * Sent from client to inform the connection is alive. */ @@ -300,6 +228,20 @@ object UserConnectionAliveReqMsg { val NAME = "UserConnectionAliveReqMsg" } case class UserConnectionAliveReqMsg(header: BbbClientMsgHeader, body: UserConnectionAliveReqMsgBody) extends StandardMsg case class UserConnectionAliveReqMsgBody(userId: String, networkRttInMs: Double) +/** + * Sent from client to update clientSettings. + */ +object SetUserClientSettingsReqMsg { val NAME = "SetUserClientSettingsReqMsg" } +case class SetUserClientSettingsReqMsg(header: BbbClientMsgHeader, body: SetUserClientSettingsReqMsgBody) extends StandardMsg +case class SetUserClientSettingsReqMsgBody(userClientSettingsJson: Map[String, Any]) + +/** + * Sent from client to inform the echo test is running. + */ +object SetUserEchoTestRunningReqMsg { val NAME = "SetUserEchoTestRunningReqMsg" } +case class SetUserEchoTestRunningReqMsg(header: BbbClientMsgHeader, body: SetUserEchoTestRunningReqMsgBody) extends StandardMsg +case class SetUserEchoTestRunningReqMsgBody() + /** * Sent to all clients about a user mobile flag. */ @@ -381,13 +323,6 @@ case class LockSettingsInMeetingChangedEvtMsgBody(disableCam: Boolean, disableMi disablePubChat: Boolean, disableNotes: Boolean, hideUserList: Boolean, lockOnJoin: Boolean, lockOnJoinConfigurable: Boolean, hideViewersCursor: Boolean, hideViewersAnnotation: Boolean, setBy: String) -/** - * Sent by client to query the lock settings. - */ -object GetLockSettingsReqMsg { val NAME = "GetLockSettingsReqMsg" } -case class GetLockSettingsReqMsg(header: BbbClientMsgHeader, body: GetLockSettingsReqMsgBody) extends StandardMsg -case class GetLockSettingsReqMsgBody(requesterId: String) - /** * Response to the query for lock settings. */ @@ -410,14 +345,7 @@ case class LogoutAndEndMeetingCmdMsgBody(userId: String) object UserJoinMeetingReqMsg { val NAME = "UserJoinMeetingReqMsg" } case class UserJoinMeetingReqMsg(header: BbbClientMsgHeader, body: UserJoinMeetingReqMsgBody) extends StandardMsg -case class UserJoinMeetingReqMsgBody(userId: String, authToken: String, clientType: String) - -/** - * Sent from Flash client to rejoin meeting after reconnection - */ -object UserJoinMeetingAfterReconnectReqMsg { val NAME = "UserJoinMeetingAfterReconnectReqMsg" } -case class UserJoinMeetingAfterReconnectReqMsg(header: BbbClientMsgHeader, body: UserJoinMeetingAfterReconnectReqMsgBody) extends StandardMsg -case class UserJoinMeetingAfterReconnectReqMsgBody(userId: String, authToken: String, clientType: String) +case class UserJoinMeetingReqMsgBody(userId: String, authToken: String, clientType: String, clientIsMobile: Boolean) /** * Sent from client to bbb-akka to notify that a user is leaving @@ -426,48 +354,6 @@ object UserLeaveReqMsg { val NAME = "UserLeaveReqMsg" } case class UserLeaveReqMsg(header: BbbClientMsgHeader, body: UserLeaveReqMsgBody) extends StandardMsg case class UserLeaveReqMsgBody(userId: String, sessionId: String, loggedOut: Boolean) -object GetUsersMeetingReqMsg { val NAME = "GetUsersMeetingReqMsg" } -case class GetUsersMeetingReqMsg(header: BbbClientMsgHeader, body: GetUsersMeetingReqMsgBody) extends StandardMsg -case class GetUsersMeetingReqMsgBody(userId: String) - -object GetUsersMeetingRespMsg { - val NAME = "GetUsersMeetingRespMsg" - - def apply(meetingId: String, userId: String, users: Vector[WebUser]): GetUsersMeetingRespMsg = { - val header = BbbClientMsgHeader(GetUsersMeetingRespMsg.NAME, meetingId, userId) - - val body = GetUsersMeetingRespMsgBody(users) - GetUsersMeetingRespMsg(header, body) - } - -} -case class GetUsersMeetingRespMsg(header: BbbClientMsgHeader, body: GetUsersMeetingRespMsgBody) extends BbbCoreMsg -case class GetUsersMeetingRespMsgBody(users: Vector[WebUser]) -case class WebUser(intId: String, extId: String, name: String, role: String, - guest: Boolean, authed: Boolean, guestStatus: String, - emoji: String, locked: Boolean, - presenter: Boolean, avatar: String, clientType: String) - -object SyncGetUsersMeetingRespMsg { val NAME = "SyncGetUsersMeetingRespMsg" } -case class SyncGetUsersMeetingRespMsg(header: BbbClientMsgHeader, body: SyncGetUsersMeetingRespMsgBody) extends BbbCoreMsg -case class SyncGetUsersMeetingRespMsgBody(users: Vector[WebUser]) - -object GetVoiceUsersMeetingRespMsg { - val NAME = "GetVoiceUsersMeetingRespMsg" - - def apply(meetingId: String, userId: String, users: Vector[VoiceConfUser]): GetVoiceUsersMeetingRespMsg = { - val header = BbbClientMsgHeader(GetVoiceUsersMeetingRespMsg.NAME, meetingId, userId) - - val body = GetVoiceUsersMeetingRespMsgBody(users) - GetVoiceUsersMeetingRespMsg(header, body) - } -} - -case class GetVoiceUsersMeetingRespMsg(header: BbbClientMsgHeader, body: GetVoiceUsersMeetingRespMsgBody) extends BbbCoreMsg -case class GetVoiceUsersMeetingRespMsgBody(users: Vector[VoiceConfUser]) -case class VoiceConfUser(intId: String, voiceUserId: String, callingWith: String, callerName: String, - callerNum: String, color: String, muted: Boolean, talking: Boolean, listenOnly: Boolean) - /** * Sent from client to add user to the presenter group of a meeting. */ @@ -526,6 +412,14 @@ object UserSpeechLocaleChangedEvtMsg { val NAME = "UserSpeechLocaleChangedEvtMsg case class UserSpeechLocaleChangedEvtMsg(header: BbbClientMsgHeader, body: UserSpeechLocaleChangedEvtMsgBody) extends BbbCoreMsg case class UserSpeechLocaleChangedEvtMsgBody(locale: String, provider: String) +object SetUserCaptionLocaleReqMsg { val NAME = "SetUserCaptionLocaleReqMsg" } +case class SetUserCaptionLocaleReqMsg(header: BbbClientMsgHeader, body: SetUserCaptionLocaleReqMsgBody) extends StandardMsg +case class SetUserCaptionLocaleReqMsgBody(locale: String, provider: String) + +object UserCaptionLocaleChangedEvtMsg { val NAME = "UserCaptionLocaleChangedEvtMsg" } +case class UserCaptionLocaleChangedEvtMsg(header: BbbClientMsgHeader, body: UserCaptionLocaleChangedEvtMsgBody) extends BbbCoreMsg +case class UserCaptionLocaleChangedEvtMsgBody(locale: String, provider: String) + object SetUserSpeechOptionsReqMsg { val NAME = "SetUserSpeechOptionsReqMsg" } case class SetUserSpeechOptionsReqMsg(header: BbbClientMsgHeader, body: SetUserSpeechOptionsReqMsgBody) extends StandardMsg case class SetUserSpeechOptionsReqMsgBody(partialUtterances: Boolean, minUtteranceLength: Int) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala index 86d878e6c1..7ae1c2cc44 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/VoiceConfMsgs.scala @@ -32,26 +32,6 @@ case class ScreenshareRtmpBroadcastStartedEvtMsgBody(voiceConf: String, screensh stream: String, vidWidth: Int, vidHeight: Int, timestamp: String, hasAudio: Boolean, contentType: String) -/** - * Sync screenshare state with bbb-html5 - */ -object SyncGetScreenshareInfoRespMsg { val NAME = "SyncGetScreenshareInfoRespMsg" } -case class SyncGetScreenshareInfoRespMsg( - header: BbbClientMsgHeader, - body: SyncGetScreenshareInfoRespMsgBody -) extends BbbCoreMsg -case class SyncGetScreenshareInfoRespMsgBody( - isBroadcasting: Boolean, - voiceConf: String, - screenshareConf: String, - stream: String, - vidWidth: Int, - vidHeight: Int, - timestamp: String, - hasAudio: Boolean, - contentType: String -) - /** * Send by FS that RTMP stream has stopped. */ @@ -517,13 +497,6 @@ case class UserDisconnectedFromGlobalAudioMsg( ) extends VoiceStandardMsg case class UserDisconnectedFromGlobalAudioMsgBody(userId: String, name: String) -/** - * Sync voice users with html5 client - */ -object SyncGetVoiceUsersRespMsg { val NAME = "SyncGetVoiceUsersRespMsg" } -case class SyncGetVoiceUsersRespMsg(header: BbbClientMsgHeader, body: SyncGetVoiceUsersRespMsgBody) extends BbbCoreMsg -case class SyncGetVoiceUsersRespMsgBody(voiceUsers: Vector[VoiceConfUser]) - /** * Received from FS that a user has become a floor holder */ @@ -555,6 +528,7 @@ case class VoiceConfCallStateEvtMsgBody( callSession: String, clientSession: String, userId: String, + voiceUserId: String, callerName: String, callState: String, origCallerIdName: String, @@ -640,7 +614,8 @@ case class GetMicrophonePermissionRespMsgBody( voiceConf: String, userId: String, sfuSessionId: String, - allowed: Boolean + allowed: Boolean, + muteOnStart: Boolean ) /** @@ -685,6 +660,7 @@ case class ToggleListenOnlyModeSysMsg( case class ToggleListenOnlyModeSysMsgBody( voiceConf: String, userId: String, + callerNum: String, enabled: Boolean ) @@ -701,5 +677,6 @@ case class ListenOnlyModeToggledInSfuEvtMsgBody( meetingId: String, voiceConf: String, userId: String, + callerNum: String, enabled: Boolean ) diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WebcamsMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WebcamsMsgs.scala index dc11b3db8f..c665e5a91e 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WebcamsMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WebcamsMsgs.scala @@ -179,17 +179,3 @@ case class CamStreamSubscribedInSfuEvtMsgBody( subscriberStreamId: String, sfuSessionId: String // Subscriber's SFU session ID ) - -/** - * Sync webcam state with bbb-html5 - */ -object SyncGetWebcamInfoRespMsg { val NAME = "SyncGetWebcamInfoRespMsg" } -case class SyncGetWebcamInfoRespMsg( - header: BbbClientMsgHeader, - body: SyncGetWebcamInfoRespMsgBody -) extends BbbCoreMsg - -case class SyncGetWebcamInfoRespMsgBody( - webcamListSync: Vector[WebcamStreamInfo] -) -case class WebcamStreamInfo(stream: String, userId: String, name: String, pin: Boolean, floor: Boolean, lastFloorTime: String) diff --git a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/util/JsonUtilTest.scala b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/util/JsonUtilTest.scala index 7d65d24d2b..2f756b457c 100755 --- a/bbb-common-message/src/test/scala/org/bigbluebutton/common2/util/JsonUtilTest.scala +++ b/bbb-common-message/src/test/scala/org/bigbluebutton/common2/util/JsonUtilTest.scala @@ -49,56 +49,6 @@ class JsonUtilTest extends UnitSpec2 with TestFixtures { println(group) } - "JsonUtil" should "unmarshall a ValidateAuthTokenReq" in { - val header: BbbClientMsgHeader = new BbbClientMsgHeader("foo", "mId", "uId") - val body: ValidateAuthTokenReqMsgBody = new ValidateAuthTokenReqMsgBody(userId = "uId", authToken = "myToken") - val msg: ValidateAuthTokenReqMsg = new ValidateAuthTokenReqMsg(header, body) - val json = JsonUtil.toJson(msg) - println(json) - val map = JsonUtil.toMap[Map[String, Any]](json) - println(map) - val finalMsg = JsonUtil.fromJson[ValidateAuthTokenReqMsg](json) - println(finalMsg) - } - - "JsonUtil" should "throw exception on invalid message" in { - val jsonMsg = - """ - |{ - | "header": { - | "name": "foo", - | "meetingId": "mId" - | }, - | "body": { - | "meetingId": "mId", - | "userId": "uId", - | "token": "myToken", - | "replyTo": "replyHere", - | "sessionId": "mySessionId" - | } - |} - """.stripMargin - - val finalMsg = JsonUtil.fromJson[FooNode](jsonMsg) - - val json = JsonUtil.toJson(finalMsg) - - val finalMsg2 = for { - result <- JsonUtil.fromJson[ValidateAuthTokenReqMsg](json) - } yield result - - println(finalMsg2) - val map = JsonUtil.toMap[Map[String, Any]](jsonMsg) - map match { - case Success(m) => - for { - header <- m.get("header") - meetingId <- header.get("meetingId") - } yield println(meetingId) - case Failure(ex) => fail("Failed to convert message.") - } - - } } case class FooNode(header: BbbCoreHeaderWithMeetingId, body: JsonNode) diff --git a/bbb-common-web/build.sbt b/bbb-common-web/build.sbt index cf124c0652..60cb8fee69 100755 --- a/bbb-common-web/build.sbt +++ b/bbb-common-web/build.sbt @@ -113,5 +113,6 @@ libraryDependencies ++= Seq( "commons-validator" % "commons-validator" % "1.7", "org.apache.tika" % "tika-core" % "2.8.0", "org.apache.tika" % "tika-parsers-standard-package" % "2.8.0", - "org.scala-lang.modules" %% "scala-xml" % "2.2.0" + "org.scala-lang.modules" %% "scala-xml" % "2.2.0", + "jakarta.ws.rs" % "jakarta.ws.rs-api" % "3.1.0" ) diff --git a/bbb-common-web/deploy.sh b/bbb-common-web/deploy.sh index 6aa4e11f2b..85ef5a6de0 100755 --- a/bbb-common-web/deploy.sh +++ b/bbb-common-web/deploy.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e #Publish new bbb-common-web .jar sbt clean diff --git a/bbb-common-web/project/Dependencies.scala b/bbb-common-web/project/Dependencies.scala index 5c0d2b1609..d321192931 100644 --- a/bbb-common-web/project/Dependencies.scala +++ b/bbb-common-web/project/Dependencies.scala @@ -19,6 +19,7 @@ object Dependencies { val freemarker = "2.3.31" val apacheHttp = "4.5.13" val apacheHttpAsync = "4.1.4" + val jsoup = "1.14.3" // Office and document conversion val apachePoi = "5.1.0" @@ -54,6 +55,7 @@ object Dependencies { val freemarker = "org.freemarker" % "freemarker" % Versions.freemarker val apacheHttp = "org.apache.httpcomponents" % "httpclient" % Versions.apacheHttp val apacheHttpAsync = "org.apache.httpcomponents" % "httpasyncclient" % Versions.apacheHttpAsync + val jsoup = "org.jsoup" % "jsoup" % Versions.jsoup val poiXml = "org.apache.poi" % "poi-ooxml" % Versions.apachePoi val nuProcess = "com.zaxxer" % "nuprocess" % Versions.nuProcess @@ -93,6 +95,7 @@ object Dependencies { Compile.freemarker, Compile.apacheHttp, Compile.apacheHttpAsync, + Compile.jsoup, Compile.poiXml, Compile.nuProcess, Compile.tika, diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java index 0c51f71846..2de1966241 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java @@ -37,6 +37,7 @@ public class ApiParams { public static final String MEETING_LAYOUT = "meetingLayout"; public static final String IS_BREAKOUT = "isBreakout"; public static final String LOGO = "logo"; + public static final String DARK_LOGO = "darklogo"; public static final String LOGOUT_TIMER = "logoutTimer"; public static final String LOGIN_URL = "loginURL"; public static final String LOGOUT_URL = "logoutURL"; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java index dbf722a79d..2269382841 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/MeetingService.java @@ -45,7 +45,6 @@ import org.bigbluebutton.api2.domain.UploadedTrack; import org.bigbluebutton.common2.redis.RedisStorageService; import org.bigbluebutton.presentation.PresentationUrlDownloadService; import org.bigbluebutton.presentation.imp.SlidesGenerationProgressNotifier; -import org.bigbluebutton.web.services.WaitingGuestCleanupTimerTask; import org.bigbluebutton.web.services.UserCleanupTimerTask; import org.bigbluebutton.web.services.EnteredUserCleanupTimerTask; import org.bigbluebutton.web.services.callback.CallbackUrlService; @@ -79,7 +78,6 @@ public class MeetingService implements MessageListener { private RecordingService recordingService; private LearningDashboardService learningDashboardService; - private WaitingGuestCleanupTimerTask waitingGuestCleaner; private UserCleanupTimerTask userCleaner; private EnteredUserCleanupTimerTask enteredUserCleaner; private StunTurnService stunTurnService; @@ -124,13 +122,13 @@ public class MeetingService implements MessageListener { public void registerUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, - String authToken, String sessionToken, String avatarURL, Boolean guest, + String authToken, String sessionToken, String avatarURL, String webcamBackgroundURL, Boolean guest, Boolean authed, String guestStatus, Boolean excludeFromDashboard, Boolean leftGuestLobby, - String enforceLayout, Map customParameters) { + String enforceLayout, Map userMetadata) { handle( new RegisterUser(meetingID, internalUserId, fullname, role, - externUserID, authToken, sessionToken, avatarURL, guest, authed, guestStatus, - excludeFromDashboard, leftGuestLobby, enforceLayout, customParameters + externUserID, authToken, sessionToken, avatarURL, webcamBackgroundURL, guest, authed, guestStatus, + excludeFromDashboard, leftGuestLobby, enforceLayout, userMetadata ) ); @@ -259,31 +257,10 @@ public class MeetingService implements MessageListener { } } - /** - * Remove registered waiting guest users who left the waiting page. - */ - public void purgeWaitingGuestUsers() { - for (AbstractMap.Entry entry : this.meetings.entrySet()) { - Long now = System.currentTimeMillis(); - Meeting meeting = entry.getValue(); - ConcurrentMap users = meeting.getUsersMap(); - for (AbstractMap.Entry registeredUser : meeting.getRegisteredUsers().entrySet()) { - String registeredUserID = registeredUser.getKey(); - RegisteredUser ru = registeredUser.getValue(); - - long elapsedTime = now - ru.getGuestWaitedOn(); - if (elapsedTime >= waitingGuestUsersTimeout && ru.getGuestStatus() == GuestPolicy.WAIT) { - log.info("Purging user [{}]", registeredUserID); - if (meeting.userUnregistered(registeredUserID) != null) { - gw.guestWaitingLeft(meeting.getInternalId(), registeredUserID); - meeting.setLeftGuestLobby(registeredUserID, true); - }; - } - } - } + public void sendChatMessage(String meetingId, String name, String message) { + gw.sendChatMessage(new ChatMessageFromApi(meetingId, name, message)); } - private void kickOffProcessingOfRecording(Meeting m) { if (m.isRecord() && m.getNumUsers() == 0) { processRecording(m); @@ -446,13 +423,13 @@ public class MeetingService implements MessageListener { m.getWebcamsOnlyForModerator(), m.getMeetingCameraCap(), m.getUserCameraCap(), m.getMaxPinnedCameras(), m.getModeratorPassword(), m.getViewerPassword(), m.getLearningDashboardAccessToken(), m.getCreateTime(), formatPrettyDate(m.getCreateTime()), m.isBreakout(), m.getSequence(), m.isFreeJoin(), m.getMetadata(), - m.getGuestPolicy(), m.getAuthenticatedGuest(), m.getAllowPromoteGuestToModerator(), m.getMeetingLayout(), m.getWelcomeMessageTemplate(), m.getWelcomeMessage(), - m.getModeratorOnlyMessage(), m.getDialNumber(), m.getMaxUsers(), m.getMaxUserConcurrentAccesses(), + m.getGuestPolicy(), m.getAuthenticatedGuest(), m.getAllowPromoteGuestToModerator(), m.getWaitingGuestUsersTimeout(), m.getMeetingLayout(), m.getWelcomeMessageTemplate(), m.getWelcomeMessage(), + m.getWelcomeMsgForModerators(), m.getDialNumber(), m.getMaxUsers(), m.getMaxUserConcurrentAccesses(), m.getMeetingExpireIfNoUserJoinedInMinutes(), m.getMeetingExpireWhenLastUserLeftInMinutes(), m.getUserInactivityInspectTimerInMinutes(), m.getUserInactivityThresholdInMinutes(), m.getUserActivitySignResponseDelayInMinutes(), m.getEndWhenNoModerator(), m.getEndWhenNoModeratorDelayInMinutes(), m.getMuteOnStart(), m.getAllowModsToUnmuteUsers(), m.getAllowModsToEjectCameras(), m.getMeetingKeepEvents(), - m.breakoutRoomsParams, m.lockSettingsParams, m.getLoginUrl(), m.getLogoutUrl(), m.getCustomLogoURL(), + m.breakoutRoomsParams, m.lockSettingsParams, m.getLoginUrl(), m.getLogoutUrl(), m.getCustomLogoURL(), m.getCustomDarkLogoURL(), m.getBannerText(), m.getBannerColor(), m.getGroups(), m.getDisabledFeatures(), m.getNotifyRecordingIsOn(), m.getPresentationUploadExternalDescription(), m.getPresentationUploadExternalUrl(), m.getOverrideClientSettings()); @@ -469,8 +446,8 @@ public class MeetingService implements MessageListener { private void processRegisterUser(RegisterUser message) { gw.registerUser(message.meetingID, message.internalUserId, message.fullname, message.role, - message.externUserID, message.authToken, message.sessionToken, message.avatarURL, message.guest, - message.authed, message.guestStatus, message.excludeFromDashboard, message.enforceLayout, message.customParameters); + message.externUserID, message.authToken, message.sessionToken, message.avatarURL, message.webcamBackgroundURL, message.guest, + message.authed, message.guestStatus, message.excludeFromDashboard, message.enforceLayout, message.userMetadata); } public Meeting getMeeting(String meetingId) { @@ -965,7 +942,7 @@ public class MeetingService implements MessageListener { } User user = new User(message.userId, message.externalUserId, - message.name, message.role, message.locked, message.avatarURL, message.guest, message.guestStatus, + message.name, message.role, message.locked, message.avatarURL, message.webcamBackgroundURL, message.guest, message.guestStatus, message.clientType); if(m.getMaxUsers() > 0 && m.countUniqueExtIds() >= m.getMaxUsers()) { @@ -1085,7 +1062,7 @@ public class MeetingService implements MessageListener { } else { if (message.userId.startsWith("v_")) { // A dial-in user joined the meeting. Dial-in users by convention has userId that starts with "v_". - User vuser = new User(message.userId, message.userId, message.name, "DIAL-IN-USER", true, "", + User vuser = new User(message.userId, message.userId, message.name, "DIAL-IN-USER", true, "", "", true, GuestPolicy.ALLOW, "DIAL-IN"); vuser.setVoiceJoined(true); m.userJoined(vuser); @@ -1349,7 +1326,6 @@ public class MeetingService implements MessageListener { public void stop() { processMessage = false; - waitingGuestCleaner.stop(); userCleaner.stop(); enteredUserCleaner.stop(); } @@ -1374,12 +1350,6 @@ public class MeetingService implements MessageListener { this.gw = gw; } - public void setWaitingGuestCleanupTimerTask(WaitingGuestCleanupTimerTask c) { - waitingGuestCleaner = c; - waitingGuestCleaner.setMeetingService(this); - waitingGuestCleaner.start(); - } - public void setEnteredUserCleanupTimerTask(EnteredUserCleanupTimerTask c) { enteredUserCleaner = c; enteredUserCleaner.setMeetingService(this); diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java index 9326aa0efd..7464048efc 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/ParamsProcessorUtil.java @@ -30,6 +30,11 @@ import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.safety.Safelist; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.RandomStringUtils; @@ -72,14 +77,17 @@ public class ParamsProcessorUtil { private String defaultHTML5ClientUrl; private String graphqlWebsocketUrl; - private String defaultGuestWaitURL; + private String graphqlApiUrl; private Boolean allowRequestsWithoutSession = false; private Integer defaultHttpSessionTimeout = 14400; private Boolean useDefaultAvatar = false; private String defaultAvatarURL; + private Boolean useDefaultWebcamBackground = false; + private String defaultWebcamBackgroundURL; private String defaultGuestPolicy; private Boolean authenticatedGuest; private Boolean defaultAllowPromoteGuestToModerator; + private Long waitingGuestUsersTimeout; private String defaultMeetingLayout; private int defaultMeetingDuration; private boolean disableRecordingDefault; @@ -99,7 +107,9 @@ public class ParamsProcessorUtil { private boolean defaultNotifyRecordingIsOn = false; private boolean defaultKeepEvents = false; private Boolean useDefaultLogo; + private Boolean useDefaultDarkLogo; private String defaultLogoURL; + private String defaultDarkLogoURL; private String defaultPresentationUploadExternalDescription = ""; private String defaultPresentationUploadExternalUrl = ""; @@ -471,10 +481,11 @@ public class ParamsProcessorUtil { isBreakout = Boolean.valueOf(params.get(ApiParams.IS_BREAKOUT)); } - String welcomeMessageTemplate = processWelcomeMessage( - params.get(ApiParams.WELCOME), isBreakout); - String welcomeMessage = substituteKeywords(welcomeMessageTemplate, - dialNumber, telVoice, meetingName); + String welcomeMessageTemplate = processWelcomeMessage(params.get(ApiParams.WELCOME), isBreakout); + String welcomeMessage = substituteKeywords(welcomeMessageTemplate,dialNumber, telVoice, meetingName); + welcomeMessage = sanitizeHtmlRemovingUnsafeTags(welcomeMessage); + welcomeMessage = welcomeMessage.replace("href=\"event:", "href=\""); + welcomeMessage = insertBlankTargetToLinks(welcomeMessage); String internalMeetingId = convertToInternalMeetingId(externalMeetingId); @@ -735,6 +746,7 @@ public class ParamsProcessorUtil { } String avatarURL = useDefaultAvatar ? defaultAvatarURL : ""; + String webcamBackgroundURL = useDefaultWebcamBackground ? defaultWebcamBackgroundURL : ""; if(defaultAllowDuplicateExtUserid == false) { log.warn("[DEPRECATION] use `maxUserConcurrentAccesses=1` instead of `allowDuplicateExtUserid=false`"); @@ -754,6 +766,7 @@ public class ParamsProcessorUtil { .withTelVoice(telVoice).withWebVoice(webVoice) .withDialNumber(dialNumber) .withDefaultAvatarURL(avatarURL) + .withDefaultWebcamBackgroundURL(webcamBackgroundURL) .withAutoStartRecording(autoStartRec) .withAllowStartStopRecording(allowStartStoptRec) .withRecordFullDurationMedia(_recordFullDurationMedia) @@ -763,10 +776,12 @@ public class ParamsProcessorUtil { .withMaxPinnedCameras(maxPinnedCameras) .withMetadata(meetingInfo) .withWelcomeMessageTemplate(welcomeMessageTemplate) - .withWelcomeMessage(welcomeMessage).isBreakout(isBreakout) + .withWelcomeMessage(welcomeMessage) + .withIsBreakout(isBreakout) .withGuestPolicy(guestPolicy) .withAuthenticatedGuest(authenticatedGuest) .withAllowPromoteGuestToModerator(allowPromoteGuestToModerator) + .withWaitingGuestUsersTimeout(waitingGuestUsersTimeout) .withAllowRequestsWithoutSession(allowRequestsWithoutSession) .withMeetingLayout(meetingLayout) .withBreakoutRoomsParams(breakoutParams) @@ -783,9 +798,12 @@ public class ParamsProcessorUtil { if (!StringUtils.isEmpty(params.get(ApiParams.MODERATOR_ONLY_MESSAGE))) { String moderatorOnlyMessageTemplate = params.get(ApiParams.MODERATOR_ONLY_MESSAGE); - String moderatorOnlyMessage = substituteKeywords(moderatorOnlyMessageTemplate, - dialNumber, telVoice, meetingName); - meeting.setModeratorOnlyMessage(moderatorOnlyMessage); + String welcomeMsgForModerators = substituteKeywords(moderatorOnlyMessageTemplate, dialNumber, telVoice, meetingName); + welcomeMsgForModerators = sanitizeHtmlRemovingUnsafeTags(welcomeMsgForModerators); + welcomeMsgForModerators = welcomeMsgForModerators.replace("href=\"event:", "href=\""); + welcomeMsgForModerators = insertBlankTargetToLinks(welcomeMsgForModerators); + + meeting.setWelcomeMsgForModerators(welcomeMsgForModerators); } if (!StringUtils.isEmpty(params.get(ApiParams.MEETING_ENDED_CALLBACK_URL))) { @@ -818,6 +836,16 @@ public class ParamsProcessorUtil { meeting.setCustomLogoURL(this.getDefaultLogoURL()); } + if (!StringUtils.isEmpty(params.get(ApiParams.DARK_LOGO))) { + meeting.setCustomDarkLogoURL(params.get(ApiParams.DARK_LOGO)); + } else if (!StringUtils.isEmpty(params.get(ApiParams.LOGO))) { + meeting.setCustomDarkLogoURL(params.get(ApiParams.LOGO)); + } else if (this.getUseDefaultDarkLogo()) { + meeting.setCustomDarkLogoURL(this.getDefaultDarkLogoURL()); + } else if (!this.getUseDefaultDarkLogo() && this.getUseDefaultLogo()) { + meeting.setCustomDarkLogoURL(this.getDefaultLogoURL()); + } + if (!StringUtils.isEmpty(params.get(ApiParams.COPYRIGHT))) { meeting.setCustomCopyright(params.get(ApiParams.COPYRIGHT)); } @@ -875,18 +903,26 @@ public class ParamsProcessorUtil { return graphqlWebsocketUrl; } - public String getDefaultGuestWaitURL() { - return defaultGuestWaitURL; - } + public String getGraphqlApiUrl() { + return graphqlApiUrl; + } public Boolean getUseDefaultLogo() { return useDefaultLogo; } + public Boolean getUseDefaultDarkLogo() { + return useDefaultDarkLogo; + } + public String getDefaultLogoURL() { return defaultLogoURL; } + public String getDefaultDarkLogoURL() { + return defaultDarkLogoURL; + } + public Boolean getAllowRequestsWithoutSession() { return allowRequestsWithoutSession; } @@ -929,6 +965,27 @@ public class ParamsProcessorUtil { return welcomeMessage; } + public String sanitizeHtmlRemovingUnsafeTags(String original) { + Safelist safelist = new Safelist() + .addTags("a", "b", "br", "i", "img", "li", "small", "span", "strong", "u", "ul") + .addAttributes("a", "href", "target") + .addAttributes("img", "src", "width", "height") + .addProtocols("a", "href", "https", "mailto", "tel"); + + return Jsoup.clean(original, safelist); + } + + private static String insertBlankTargetToLinks(String html) { + Document document = Jsoup.parse(html); + Elements links = document.select("a[href]"); // Select all elements with an href attribute + + for (Element link : links) { + link.attr("target", "_blank"); // Set target="_blank" attribute + } + + return document.body().html(); // Return the modified HTML + } + public String convertToInternalMeetingId(String extMeetingId) { return DigestUtils.sha1Hex(extMeetingId); } @@ -1221,18 +1278,27 @@ public class ParamsProcessorUtil { this.graphqlWebsocketUrl = graphqlWebsocketUrl.replace("https://","wss://"); } - public void setDefaultGuestWaitURL(String url) { - this.defaultGuestWaitURL = url; - } + public void setGraphqlApiUrl(String graphqlApiUrl) { + this.graphqlApiUrl = graphqlApiUrl; + } public void setUseDefaultLogo(Boolean value) { this.useDefaultLogo = value; } + public void setUseDefaultDarkLogo(Boolean value) { + this.useDefaultDarkLogo = value; + } + + public void setDefaultLogoURL(String url) { this.defaultLogoURL = url; } + public void setDefaultDarkLogoURL(String url) { + this.defaultDarkLogoURL = url; + } + public void setAllowRequestsWithoutSession(Boolean allowRequestsWithoutSession) { this.allowRequestsWithoutSession = allowRequestsWithoutSession; } @@ -1285,10 +1351,18 @@ public class ParamsProcessorUtil { this.useDefaultAvatar = value; } - public void setdefaultAvatarURL(String url) { + public void setDefaultAvatarURL(String url) { this.defaultAvatarURL = url; } + public void setUseDefaultWebcamBackground(Boolean value) { + this.useDefaultWebcamBackground = value; + } + + public void setDefaultWebcamBackgroundURL(String uri) { + this.defaultWebcamBackgroundURL = uri; + } + public void setDefaultGuestPolicy(String guestPolicy) { this.defaultGuestPolicy = guestPolicy; } @@ -1297,11 +1371,15 @@ public class ParamsProcessorUtil { this.authenticatedGuest = value; } - public void setDefaultAllowPromoteGuestToModerator(Boolean value) { - this.defaultAllowPromoteGuestToModerator = value; - } + public void setDefaultAllowPromoteGuestToModerator(Boolean value) { + this.defaultAllowPromoteGuestToModerator = value; + } - public void setDefaultMeetingLayout(String meetingLayout) { + public void setWaitingGuestUsersTimeout(Long value) { + this.waitingGuestUsersTimeout = value; + } + + public void setDefaultMeetingLayout(String meetingLayout) { this.defaultMeetingLayout = meetingLayout; } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java index 3d45e3b928..42b1a3a0f9 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/Meeting.java @@ -59,7 +59,7 @@ public class Meeting { private Boolean notifyRecordingIsOn; private String welcomeMsgTemplate; private String welcomeMsg; - private String modOnlyMessage = ""; + private String welcomeMsgForModerators = ""; private String loginUrl; private String logoutUrl; private int logoutTimer = 0; @@ -77,11 +77,13 @@ public class Meeting { private Integer maxPinnedCameras = 0; private String dialNumber; private String defaultAvatarURL; + private String defaultWebcamBackgroundURL; private String guestPolicy = GuestPolicy.ASK_MODERATOR; private String guestLobbyMessage = ""; private Map usersWithGuestLobbyMessages; private Boolean authenticatedGuest = false; private Boolean allowPromoteGuestToModerator = false; + private long waitingGuestUsersTimeout = 30000; private String meetingLayout = MeetingLayout.SMART_LAYOUT; private boolean userHasJoined = false; private Map guestUsersWithPositionInWaitingLine; @@ -94,6 +96,7 @@ public class Meeting { private final List breakoutRooms = new ArrayList<>(); private ArrayList groups = new ArrayList(); private String customLogoURL = ""; + private String customDarkLogoURL = ""; private String customCopyright = ""; private Boolean muteOnStart = false; private Boolean allowModsToUnmuteUsers = false; @@ -147,6 +150,7 @@ public class Meeting { logoutUrl = builder.logoutUrl; logoutTimer = builder.logoutTimer; defaultAvatarURL = builder.defaultAvatarURL; + defaultWebcamBackgroundURL = builder.defaultWebcamBackgroundURL; record = builder.record; autoStartRecording = builder.autoStartRecording; allowStartStopRecording = builder.allowStartStopRecording; @@ -166,8 +170,9 @@ public class Meeting { isBreakout = builder.isBreakout; guestPolicy = builder.guestPolicy; authenticatedGuest = builder.authenticatedGuest; - allowPromoteGuestToModerator = builder.allowPromoteGuestToModerator; - meetingLayout = builder.meetingLayout; + allowPromoteGuestToModerator = builder.allowPromoteGuestToModerator; + waitingGuestUsersTimeout = builder.waitingGuestUsersTimeout; + meetingLayout = builder.meetingLayout; allowRequestsWithoutSession = builder.allowRequestsWithoutSession; breakoutRoomsParams = builder.breakoutRoomsParams; lockSettingsParams = builder.lockSettingsParams; @@ -349,12 +354,12 @@ public class Meeting { return endTime; } - public void setModeratorOnlyMessage(String msg) { - modOnlyMessage = msg; + public void setWelcomeMsgForModerators(String msg) { + welcomeMsgForModerators = msg; } - public String getModeratorOnlyMessage() { - return modOnlyMessage; + public String getWelcomeMsgForModerators() { + return welcomeMsgForModerators; } public void setEndTime(long t) { @@ -456,6 +461,10 @@ public class Meeting { return defaultAvatarURL; } + public String getDefaultWebcamBackgroundURL() { + return defaultWebcamBackgroundURL; + } + public void setWaitingPositionsInWaitingQueue(HashMap guestUsersWithPositionInWaitingLine) { this.guestUsersWithPositionInWaitingLine = guestUsersWithPositionInWaitingLine; } @@ -511,6 +520,14 @@ public class Meeting { return allowPromoteGuestToModerator; } + public void setWaitingGuestUsersTimeout(long waitingGuestUsersTimeout) { + waitingGuestUsersTimeout = waitingGuestUsersTimeout; + } + + public long getWaitingGuestUsersTimeout() { + return waitingGuestUsersTimeout; + } + public void setMeetingLayout(String layout) { meetingLayout = layout; } @@ -633,10 +650,18 @@ public class Meeting { return customLogoURL; } + public String getCustomDarkLogoURL() { + return customDarkLogoURL; + } + public void setCustomLogoURL(String url) { customLogoURL = url; } + public void setCustomDarkLogoURL(String url) { + customDarkLogoURL = url; + } + public void setCustomCopyright(String copyright) { customCopyright = copyright; } @@ -916,11 +941,13 @@ public class Meeting { private Map metadata; private String dialNumber; private String defaultAvatarURL; + private String defaultWebcamBackgroundURL; private long createdTime; private boolean isBreakout; private String guestPolicy; private Boolean authenticatedGuest; private Boolean allowPromoteGuestToModerator; + private long waitingGuestUsersTimeout; private Boolean allowRequestsWithoutSession; private String meetingLayout; private BreakoutRoomsParams breakoutRoomsParams; @@ -1062,7 +1089,12 @@ public class Meeting { return this; } - public Builder isBreakout(Boolean b) { + public Builder withDefaultWebcamBackgroundURL(String w) { + defaultWebcamBackgroundURL = w; + return this; + } + + public Builder withIsBreakout(Boolean b) { isBreakout = b; return this; } @@ -1112,6 +1144,11 @@ public class Meeting { return this; } + public Builder withWaitingGuestUsersTimeout(long value) { + waitingGuestUsersTimeout = value; + return this; + } + public Builder withAllowRequestsWithoutSession(Boolean value) { allowRequestsWithoutSession = value; return this; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/User.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/User.java index 1440f687f1..83fb978d7d 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/User.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/User.java @@ -32,6 +32,7 @@ public class User { private String role; private Boolean locked; private String avatarURL; + private String webcamBackgroundURL; private Map status; private Boolean guest; private String guestStatus; @@ -47,6 +48,7 @@ public class User { String role, Boolean locked, String avatarURL, + String webcamBackgroundURL, Boolean guest, String guestStatus, String clientType) { @@ -56,6 +58,7 @@ public class User { this.role = role; this.locked = locked; this.avatarURL = avatarURL; + this.webcamBackgroundURL = webcamBackgroundURL; this.guest = guest; this.guestStatus = guestStatus; this.status = new ConcurrentHashMap<>(); @@ -134,6 +137,14 @@ public class User { this.avatarURL = avatarURL; } + public String getWebcamBackgroundUrl() { + return webcamBackgroundURL; + } + + public void setWebcamBackgroundUrl(String webcamBackgroundURL) { + this.webcamBackgroundURL = webcamBackgroundURL; + } + public boolean isModerator() { return "MODERATOR".equalsIgnoreCase(this.role); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/UserSession.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/UserSession.java index 53b8a248c7..09aa775016 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/UserSession.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/domain/UserSession.java @@ -43,6 +43,7 @@ public class UserSession { public String defaultLayout = "NOLAYOUT"; public String enforceLayout = ""; public String avatarURL; + public String webcamBackgroundURL; public String guestStatus = GuestPolicy.ALLOW; public String clientUrl = null; public Boolean excludeFromDashboard = false; @@ -139,6 +140,10 @@ public class UserSession { return avatarURL; } + public String getWebcamBackgroundURL() { + return webcamBackgroundURL; + } + public String getGuestStatus() { return guestStatus; } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/ChatMessageFromApi.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/ChatMessageFromApi.java new file mode 100755 index 0000000000..7571525127 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/ChatMessageFromApi.java @@ -0,0 +1,13 @@ +package org.bigbluebutton.api.messaging.messages; + +public class ChatMessageFromApi implements IMessage { + public final String meetingId; + public final String name; + public final String message; + + public ChatMessageFromApi(String meetingId, String name, String message) { + this.meetingId = meetingId; + this.name = name; + this.message = message; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/RegisterUser.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/RegisterUser.java index fb0b0b35aa..24d0c4ecf4 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/RegisterUser.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/RegisterUser.java @@ -13,18 +13,19 @@ public class RegisterUser implements IMessage { public final String authToken; public final String sessionToken; public final String avatarURL; + public final String webcamBackgroundURL; public final Boolean guest; public final Boolean authed; public final String guestStatus; public final Boolean excludeFromDashboard; public final Boolean leftGuestLobby; public final String enforceLayout; - public final Map customParameters; + public final Map userMetadata; public RegisterUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, - String authToken, String sessionToken, String avatarURL, Boolean guest, + String authToken, String sessionToken, String avatarURL, String webcamBackgroundURL, Boolean guest, Boolean authed, String guestStatus, Boolean excludeFromDashboard, Boolean leftGuestLobby, - String enforceLayout, Map customParameters) { + String enforceLayout, Map userMetadata) { this.meetingID = meetingID; this.internalUserId = internalUserId; this.fullname = fullname; @@ -33,12 +34,13 @@ public class RegisterUser implements IMessage { this.authToken = authToken; this.sessionToken = sessionToken; this.avatarURL = avatarURL; + this.webcamBackgroundURL = webcamBackgroundURL; this.guest = guest; this.authed = authed; this.guestStatus = guestStatus; this.excludeFromDashboard = excludeFromDashboard; this.leftGuestLobby = leftGuestLobby; this.enforceLayout = enforceLayout; - this.customParameters = customParameters; + this.userMetadata = userMetadata; } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserJoined.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserJoined.java index a019ad572e..eb74c31674 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserJoined.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/messaging/messages/UserJoined.java @@ -8,6 +8,7 @@ public class UserJoined implements IMessage { public final String role; public final Boolean locked; public final String avatarURL; + public final String webcamBackgroundURL; public final Boolean guest; public final String guestStatus; public final String clientType; @@ -20,6 +21,7 @@ public class UserJoined implements IMessage { String role, Boolean locked, String avatarURL, + String webcamBackgroundURL, Boolean guest, String guestStatus, String clientType) { @@ -30,6 +32,7 @@ public class UserJoined implements IMessage { this.role = role; this.locked = locked; this.avatarURL = avatarURL; + this.webcamBackgroundURL = webcamBackgroundURL; this.guest = guest; this.guestStatus = guestStatus; this.clientType = clientType; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/constraint/PostChecksumConstraint.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/constraint/ContentTypeConstraint.java old mode 100755 new mode 100644 similarity index 59% rename from bbb-common-web/src/main/java/org/bigbluebutton/api/model/constraint/PostChecksumConstraint.java rename to bbb-common-web/src/main/java/org/bigbluebutton/api/model/constraint/ContentTypeConstraint.java index 4e359b8fed..7baf6cfc42 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/constraint/PostChecksumConstraint.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/constraint/ContentTypeConstraint.java @@ -1,22 +1,22 @@ -package org.bigbluebutton.api.model.constraint; - -import org.bigbluebutton.api.model.validator.PostChecksumValidator; - -import javax.validation.Constraint; -import javax.validation.Payload; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -@Constraint(validatedBy = PostChecksumValidator.class) -@Target(TYPE) -@Retention(RUNTIME) -public @interface PostChecksumConstraint { - - String key() default "checksumError"; - String message() default "Checksums do not match"; - Class[] groups() default {}; - Class[] payload() default {}; -} +package org.bigbluebutton.api.model.constraint; + +import org.bigbluebutton.api.model.validator.ContentTypeValidator; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Constraint(validatedBy = ContentTypeValidator.class) +@Target(TYPE) +@Retention(RUNTIME) +public @interface ContentTypeConstraint { + + String key() default "unsupportedContentType"; + String message() default "POST request Content-Type is missing or unsupported"; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/CreateMeeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/CreateMeeting.java index fe027dc9c8..fbabaa3b53 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/CreateMeeting.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/CreateMeeting.java @@ -1,12 +1,16 @@ package org.bigbluebutton.api.model.request; +import jakarta.ws.rs.core.MediaType; import org.bigbluebutton.api.model.constraint.*; import org.bigbluebutton.api.model.shared.Checksum; +import javax.servlet.http.HttpServletRequest; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.Map; +import java.util.Set; +@ContentTypeConstraint public class CreateMeeting extends RequestWithChecksum { public enum Params implements RequestParameters { @@ -51,8 +55,8 @@ public class CreateMeeting extends RequestWithChecksum { private String recordString; private Boolean record; - public CreateMeeting(Checksum checksum) { - super(checksum); + public CreateMeeting(Checksum checksum, HttpServletRequest servletRequest) { + super(checksum, servletRequest); } public String getName() { @@ -138,4 +142,9 @@ public class CreateMeeting extends RequestWithChecksum { isBreakoutRoom = Boolean.parseBoolean(isBreakoutRoomString); record = Boolean.parseBoolean(recordString); } + + @Override + public Set getSupportedContentTypes() { + return Set.of(MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_XML, MediaType.TEXT_XML); + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/EndMeeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/EndMeeting.java index 55feff00df..865dd363b0 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/EndMeeting.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/EndMeeting.java @@ -1,16 +1,16 @@ package org.bigbluebutton.api.model.request; -import org.bigbluebutton.api.model.constraint.MeetingExistsConstraint; -import org.bigbluebutton.api.model.constraint.MeetingIDConstraint; -import org.bigbluebutton.api.model.constraint.NotEmpty; -import org.bigbluebutton.api.model.constraint.PasswordConstraint; +import org.bigbluebutton.api.model.constraint.*; import org.bigbluebutton.api.model.shared.Checksum; import org.bigbluebutton.api.model.shared.ModeratorPassword; import org.bigbluebutton.api.model.shared.Password; +import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import java.util.Map; +import java.util.Set; +@ContentTypeConstraint public class EndMeeting extends RequestWithChecksum { public enum Params implements RequestParameters { @@ -34,8 +34,8 @@ public class EndMeeting extends RequestWithChecksum { @Valid private Password moderatorPassword; - public EndMeeting(Checksum checksum) { - super(checksum); + public EndMeeting(Checksum checksum, HttpServletRequest servletRequest) { + super(checksum, servletRequest); moderatorPassword = new ModeratorPassword(); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Enter.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Enter.java deleted file mode 100755 index 11981e1014..0000000000 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Enter.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.bigbluebutton.api.model.request; - -import org.bigbluebutton.api.model.constraint.*; -import org.bigbluebutton.api.service.SessionService; -import javax.validation.constraints.NotNull; -import java.util.Map; - -public class Enter implements Request { - - public enum Params implements RequestParameters { - SESSION_TOKEN("sessionToken"); - - private final String value; - - Params(String value) { this.value = value; } - - public String getValue() { return value; } - } - - @UserSessionConstraint - @GuestPolicyConstraint - private String sessionToken; - - @MeetingExistsConstraint - @MeetingEndedConstraint - private String meetingID; - - private SessionService sessionService; - - public Enter() { - sessionService = new SessionService(); - } - - public String getSessionToken() { - return sessionToken; - } - - public void setSessionToken(String sessionToken) { - this.sessionToken = sessionToken; - } - - @Override - public void populateFromParamsMap(Map params) { - if(params.containsKey(Params.SESSION_TOKEN.getValue())) { - setSessionToken(params.get(Params.SESSION_TOKEN.getValue())[0]); - sessionService.setSessionToken(sessionToken); - meetingID = sessionService.getMeetingID(); - } - } - - @Override - public void convertParamsFromString() { - - } -} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Feedback.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Feedback.java new file mode 100755 index 0000000000..65a61f369c --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Feedback.java @@ -0,0 +1,44 @@ +package org.bigbluebutton.api.model.request; + +import org.bigbluebutton.api.model.constraint.UserSessionConstraint; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public class Feedback extends RequestWithSession { + + public enum Params implements RequestParameters { + SESSION_TOKEN("sessionToken"); + + private final String value; + + Params(String value) { this.value = value; } + + public String getValue() { return value; } + } + + @UserSessionConstraint + private String sessionToken; + + public Feedback(HttpServletRequest servletRequest) { + super(servletRequest); + } + + public String getSessionToken() { + return sessionToken; + } + + public void setSessionToken(String sessionToken) { + this.sessionToken = sessionToken; + } + + @Override + public void populateFromParamsMap(Map params) { + if(params.containsKey(Feedback.Params.SESSION_TOKEN.getValue())) setSessionToken(params.get(Feedback.Params.SESSION_TOKEN.getValue())[0]); + } + + @Override + public void convertParamsFromString() { + + } +} \ No newline at end of file diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/GetJoinUrl.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/GetJoinUrl.java index 96a4120e42..8c30160b20 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/GetJoinUrl.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/GetJoinUrl.java @@ -2,9 +2,10 @@ package org.bigbluebutton.api.model.request; import org.bigbluebutton.api.model.constraint.UserSessionConstraint; +import javax.servlet.http.HttpServletRequest; import java.util.Map; -public class GetJoinUrl implements Request { +public class GetJoinUrl extends RequestWithSession { public enum Params implements RequestParameters { SESSION_TOKEN("sessionToken"); @@ -19,6 +20,10 @@ public class GetJoinUrl implements Request { @UserSessionConstraint private String sessionToken; + public GetJoinUrl(HttpServletRequest servletRequest) { + super(servletRequest); + } + public String getSessionToken() { return sessionToken; } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/GuestWait.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/GuestWait.java index 2e2e3aeecc..e882d9b1a3 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/GuestWait.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/GuestWait.java @@ -1,14 +1,17 @@ package org.bigbluebutton.api.model.request; +import org.bigbluebutton.api.model.constraint.ContentTypeConstraint; import org.bigbluebutton.api.model.constraint.MeetingEndedConstraint; import org.bigbluebutton.api.model.constraint.MeetingExistsConstraint; import org.bigbluebutton.api.model.constraint.UserSessionConstraint; import org.bigbluebutton.api.service.SessionService; +import javax.servlet.http.HttpServletRequest; import javax.validation.constraints.NotNull; import java.util.Map; -public class GuestWait implements Request { +@ContentTypeConstraint +public class GuestWait extends RequestWithSession{ public enum Params implements RequestParameters { SESSION_TOKEN("sessionToken"); @@ -29,7 +32,8 @@ public class GuestWait implements Request { private SessionService sessionService; - public GuestWait() { + public GuestWait(HttpServletRequest servletRequest) { + super(servletRequest); sessionService = new SessionService(); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/InsertDocument.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/InsertDocument.java index 3d77fe8cbf..9d0d06ffd4 100644 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/InsertDocument.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/InsertDocument.java @@ -1,11 +1,14 @@ package org.bigbluebutton.api.model.request; +import jakarta.ws.rs.core.MediaType; import org.bigbluebutton.api.model.constraint.*; import org.bigbluebutton.api.model.shared.Checksum; +import javax.servlet.http.HttpServletRequest; import java.util.Map; +import java.util.Set; - +@ContentTypeConstraint public class InsertDocument extends RequestWithChecksum { public enum Params implements RequestParameters { @@ -21,8 +24,8 @@ public class InsertDocument extends RequestWithChecksum { @MeetingIDConstraint private String meetingID; - public InsertDocument(Checksum checksum) { - super(checksum); + public InsertDocument(Checksum checksum, HttpServletRequest servletRequest) { + super(checksum, servletRequest); } public String getMeetingID() { @@ -37,4 +40,9 @@ public class InsertDocument extends RequestWithChecksum { public void populateFromParamsMap(Map params) { if(params.containsKey(Params.MEETING_ID.getValue())) setMeetingID(params.get(Params.MEETING_ID.getValue())[0]); } + + @Override + public Set getSupportedContentTypes() { + return Set.of(MediaType.APPLICATION_XML, MediaType.TEXT_XML); + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/JoinMeeting.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/JoinMeeting.java index b629d9c8bb..00c80b225a 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/JoinMeeting.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/JoinMeeting.java @@ -5,9 +5,11 @@ import org.bigbluebutton.api.model.shared.Checksum; import org.bigbluebutton.api.model.shared.JoinPassword; import org.bigbluebutton.api.model.shared.Password; +import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import java.util.Map; +@ContentTypeConstraint public class JoinMeeting extends RequestWithChecksum { public enum Params implements RequestParameters { @@ -57,8 +59,8 @@ public class JoinMeeting extends RequestWithChecksum { @Valid private Password joinPassword; - public JoinMeeting(Checksum checksum) { - super(checksum); + public JoinMeeting(Checksum checksum, HttpServletRequest servletRequest) { + super(checksum, servletRequest); joinPassword = new JoinPassword(); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/LearningDashboard.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/LearningDashboard.java index a99556b373..263e729b67 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/LearningDashboard.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/LearningDashboard.java @@ -2,10 +2,11 @@ package org.bigbluebutton.api.model.request; import org.bigbluebutton.api.model.constraint.UserSessionConstraint; +import javax.servlet.http.HttpServletRequest; import javax.validation.constraints.NotNull; import java.util.Map; -public class LearningDashboard implements Request { +public class LearningDashboard extends RequestWithSession { public enum Params implements RequestParameters { SESSION_TOKEN("sessionToken"); @@ -20,6 +21,10 @@ public class LearningDashboard implements Request { @UserSessionConstraint private String sessionToken; + public LearningDashboard(HttpServletRequest servletRequest) { + super(servletRequest); + } + public String getSessionToken() { return sessionToken; } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/MeetingInfo.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/MeetingInfo.java index b6f28fc1f4..c40052f7a0 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/MeetingInfo.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/MeetingInfo.java @@ -1,11 +1,14 @@ package org.bigbluebutton.api.model.request; +import org.bigbluebutton.api.model.constraint.ContentTypeConstraint; import org.bigbluebutton.api.model.constraint.MeetingExistsConstraint; import org.bigbluebutton.api.model.constraint.MeetingIDConstraint; import org.bigbluebutton.api.model.shared.Checksum; +import javax.servlet.http.HttpServletRequest; import java.util.Map; +@ContentTypeConstraint public class MeetingInfo extends RequestWithChecksum { public enum Params implements RequestParameters { @@ -22,8 +25,8 @@ public class MeetingInfo extends RequestWithChecksum { @MeetingExistsConstraint private String meetingID; - public MeetingInfo(Checksum checksum) { - super(checksum); + public MeetingInfo(Checksum checksum, HttpServletRequest servletRequest) { + super(checksum, servletRequest); } public String getMeetingID() { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/MeetingRunning.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/MeetingRunning.java index 5f146cdcfb..8782714b0b 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/MeetingRunning.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/MeetingRunning.java @@ -1,10 +1,13 @@ package org.bigbluebutton.api.model.request; +import org.bigbluebutton.api.model.constraint.ContentTypeConstraint; import org.bigbluebutton.api.model.constraint.MeetingIDConstraint; import org.bigbluebutton.api.model.shared.Checksum; +import javax.servlet.http.HttpServletRequest; import java.util.Map; +@ContentTypeConstraint public class MeetingRunning extends RequestWithChecksum { public enum Params implements RequestParameters { @@ -20,8 +23,8 @@ public class MeetingRunning extends RequestWithChecksum { @MeetingIDConstraint private String meetingID; - public MeetingRunning(Checksum checksum) { - super(checksum); + public MeetingRunning(Checksum checksum, HttpServletRequest servletRequest) { + super(checksum, servletRequest); } public String getMeetingID() { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Request.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Request.java index ed90a90ecb..9e3cd5c76e 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Request.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Request.java @@ -1,9 +1,13 @@ package org.bigbluebutton.api.model.request; +import javax.servlet.http.HttpServletRequest; import java.util.Map; +import java.util.Set; public interface Request

& RequestParameters> { void populateFromParamsMap(Map params); void convertParamsFromString(); + Set getSupportedContentTypes(); + HttpServletRequest getServletRequest(); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/RequestWithChecksum.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/RequestWithChecksum.java index fa47bc7c0a..f86d656136 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/RequestWithChecksum.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/RequestWithChecksum.java @@ -1,17 +1,23 @@ package org.bigbluebutton.api.model.request; +import jakarta.ws.rs.core.MediaType; import org.bigbluebutton.api.model.shared.Checksum; +import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import java.util.Map; +import java.util.Set; public abstract class RequestWithChecksum

& RequestParameters> implements Request

{ @Valid protected Checksum checksum; - protected RequestWithChecksum(Checksum checksum) { + protected HttpServletRequest servletRequest; + + protected RequestWithChecksum(Checksum checksum, HttpServletRequest servletRequest) { this.checksum = checksum; + this.servletRequest = servletRequest; } public Checksum getChecksum() { @@ -27,4 +33,14 @@ public abstract class RequestWithChecksum

& RequestParameters> public void convertParamsFromString() { } + + @Override + public Set getSupportedContentTypes() { + return Set.of(MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA); + } + + @Override + public HttpServletRequest getServletRequest() { + return servletRequest; + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/RequestWithSession.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/RequestWithSession.java new file mode 100644 index 0000000000..7dc5c6445b --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/RequestWithSession.java @@ -0,0 +1,25 @@ +package org.bigbluebutton.api.model.request; + +import jakarta.ws.rs.core.MediaType; + +import javax.servlet.http.HttpServletRequest; +import java.util.Set; + +public abstract class RequestWithSession

& RequestParameters> implements Request

{ + + protected HttpServletRequest servletRequest; + + protected RequestWithSession(HttpServletRequest servletRequest) { + this.servletRequest = servletRequest; + } + + @Override + public Set getSupportedContentTypes() { + return Set.of(MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA); + } + + @Override + public HttpServletRequest getServletRequest() { + return servletRequest; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SendChatMessage.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SendChatMessage.java new file mode 100755 index 0000000000..d003fea8d8 --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SendChatMessage.java @@ -0,0 +1,72 @@ +package org.bigbluebutton.api.model.request; + +import org.bigbluebutton.api.model.constraint.MeetingIDConstraint; +import org.bigbluebutton.api.model.constraint.MeetingNameConstraint; +import org.bigbluebutton.api.model.constraint.NotNull; +import org.bigbluebutton.api.model.constraint.Size; +import org.bigbluebutton.api.model.shared.Checksum; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +public class SendChatMessage extends RequestWithChecksum { + + public enum Params implements RequestParameters { + MEETING_ID("meetingID"), + USER_NAME("userName"), + MESSAGE("message"); + + private final String value; + + Params(String value) { this.value = value; } + + public String getValue() { return value; } + } + + @MeetingIDConstraint + private String meetingID; + + private String userName; + + @NotNull(message = "You must provide the param message") + @Size(min = 1, max = 500, message = "Param message must be between 1 and 500 characters") + private String message; + + public SendChatMessage(Checksum checksum, HttpServletRequest servletRequest) { + super(checksum, servletRequest); + } + + public String getMeetingID() { + return meetingID; + } + + public void setMeetingID(String meetingID) { + this.meetingID = meetingID; + } + + @Size(max = 255, message = "Param userName must not exceed 255 characters") + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + + @Override + public void populateFromParamsMap(Map params) { + if(params.containsKey(SendChatMessage.Params.MEETING_ID.getValue())) setMeetingID(params.get(SendChatMessage.Params.MEETING_ID.getValue())[0]); + if(params.containsKey(SendChatMessage.Params.USER_NAME.getValue())) setUserName(params.get(Params.USER_NAME.getValue())[0]); + if(params.containsKey(SendChatMessage.Params.MESSAGE.getValue())) setMessage(params.get(Params.MESSAGE.getValue())[0]); + + } +} \ No newline at end of file diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SignOut.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SignOut.java index 3a0ff66122..da67b88b91 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SignOut.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SignOut.java @@ -2,10 +2,11 @@ package org.bigbluebutton.api.model.request; import org.bigbluebutton.api.model.constraint.UserSessionConstraint; +import javax.servlet.http.HttpServletRequest; import javax.validation.constraints.NotNull; import java.util.Map; -public class SignOut implements Request { +public class SignOut extends RequestWithSession { public enum Params implements RequestParameters { SESSION_TOKEN("sessionToken"); @@ -20,6 +21,10 @@ public class SignOut implements Request { @UserSessionConstraint private String sessionToken; + public SignOut(HttpServletRequest servletRequest) { + super(servletRequest); + } + public String getSessionToken() { return sessionToken; } @@ -30,7 +35,7 @@ public class SignOut implements Request { @Override public void populateFromParamsMap(Map params) { - if(params.containsKey(Enter.Params.SESSION_TOKEN.getValue())) setSessionToken(params.get(Enter.Params.SESSION_TOKEN.getValue())[0]); + if(params.containsKey(SignOut.Params.SESSION_TOKEN.getValue())) setSessionToken(params.get(SignOut.Params.SESSION_TOKEN.getValue())[0]); } @Override diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SimpleRequest.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SimpleRequest.java index 297dbdd6d4..a7ae3be80c 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SimpleRequest.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/SimpleRequest.java @@ -1,9 +1,12 @@ package org.bigbluebutton.api.model.request; +import org.bigbluebutton.api.model.constraint.ContentTypeConstraint; import org.bigbluebutton.api.model.shared.Checksum; +import javax.servlet.http.HttpServletRequest; import java.util.Map; +@ContentTypeConstraint public class SimpleRequest extends RequestWithChecksum { public enum Params implements RequestParameters { @@ -16,8 +19,8 @@ public class SimpleRequest extends RequestWithChecksum { public String getValue() { return value; } } - public SimpleRequest(Checksum checksum) { - super(checksum); + public SimpleRequest(Checksum checksum, HttpServletRequest servletRequest) { + super(checksum, servletRequest); } @Override diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Stuns.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Stuns.java index 0050906634..78b29b232b 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Stuns.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/request/Stuns.java @@ -3,9 +3,11 @@ package org.bigbluebutton.api.model.request; import org.bigbluebutton.api.model.constraint.*; import org.bigbluebutton.api.service.SessionService; +import javax.servlet.http.HttpServletRequest; import java.util.Map; -public class Stuns implements Request { +@ContentTypeConstraint +public class Stuns extends RequestWithSession { public enum Params implements RequestParameters { SESSION_TOKEN("sessionToken"); @@ -26,7 +28,10 @@ public class Stuns implements Request { private SessionService sessionService; - public Stuns() { sessionService = new SessionService(); } + public Stuns(HttpServletRequest servletRequest) { + super(servletRequest); + sessionService = new SessionService(); + } public String getSessionToken() { return sessionToken; @@ -38,8 +43,8 @@ public class Stuns implements Request { @Override public void populateFromParamsMap(Map params) { - if(params.containsKey(Enter.Params.SESSION_TOKEN.getValue())) { - setSessionToken(params.get(Enter.Params.SESSION_TOKEN.getValue())[0]); + if(params.containsKey(Stuns.Params.SESSION_TOKEN.getValue())) { + setSessionToken(params.get(Stuns.Params.SESSION_TOKEN.getValue())[0]); sessionService.setSessionToken(sessionToken); meetingID = sessionService.getMeetingID(); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/Checksum.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/Checksum.java index bc7674a0af..d6e9a231f4 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/Checksum.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/Checksum.java @@ -1,8 +1,11 @@ package org.bigbluebutton.api.model.shared; +import org.bigbluebutton.api.model.constraint.ContentTypeConstraint; import org.bigbluebutton.api.model.constraint.NotEmpty; import org.bigbluebutton.api.util.ParamsUtil; +import javax.servlet.http.HttpServletRequest; + public abstract class Checksum { @NotEmpty(message = "You must provide the API call", groups = ChecksumValidationGroup.class) @@ -13,9 +16,12 @@ public abstract class Checksum { protected String queryStringWithoutChecksum; - public Checksum(String apiCall, String checksum) { + protected HttpServletRequest request; + + public Checksum(String apiCall, String checksum, HttpServletRequest request) { this.apiCall = ParamsUtil.sanitizeString(apiCall); this.checksum = ParamsUtil.sanitizeString(checksum); + this.request = request; } public String getApiCall() { @@ -41,4 +47,12 @@ public abstract class Checksum { public void setQueryStringWithoutChecksum(String queryStringWithoutChecksum) { this.queryStringWithoutChecksum = queryStringWithoutChecksum; } + + public void setRequest(HttpServletRequest request) { + this.request = request; + } + + public HttpServletRequest getRequest() { + return request; + } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/GetChecksum.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/GetChecksum.java index 5c639fa1e8..952de208c9 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/GetChecksum.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/GetChecksum.java @@ -3,16 +3,16 @@ package org.bigbluebutton.api.model.shared; import org.bigbluebutton.api.model.constraint.GetChecksumConstraint; import org.bigbluebutton.api.util.ParamsUtil; +import javax.servlet.http.HttpServletRequest; import javax.validation.constraints.NotEmpty; @GetChecksumConstraint(groups = ChecksumValidationGroup.class) public class GetChecksum extends Checksum { - - @NotEmpty(message = "You must provide the query string") + private String queryString; - public GetChecksum(String apiCall, String checksum, String queryString) { - super(apiCall, checksum); + public GetChecksum(String apiCall, String checksum, String queryString, HttpServletRequest request) { + super(apiCall, checksum, request); this.queryString = ParamsUtil.sanitizeString(queryString); removeChecksumFromQueryString(); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/PostChecksum.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/PostChecksum.java deleted file mode 100755 index d5d72f3756..0000000000 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/shared/PostChecksum.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.bigbluebutton.api.model.shared; - -import org.bigbluebutton.api.model.constraint.PostChecksumConstraint; -import org.bigbluebutton.api.service.ValidationService; - -import java.util.Map; - -@PostChecksumConstraint(groups = ChecksumValidationGroup.class) -public class PostChecksum extends Checksum { - - Map params; - - public PostChecksum(String apiCall, String checksum, Map params) { - super(apiCall, checksum); - this.params = params; - queryStringWithoutChecksum = ValidationService.buildQueryStringFromParamsMap(params); - } - - public Map getParams() { return params; } - - public void setParams(Map params) { this.params = params; } -} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/ContentTypeValidator.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/ContentTypeValidator.java new file mode 100644 index 0000000000..b54a069b4e --- /dev/null +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/ContentTypeValidator.java @@ -0,0 +1,48 @@ +package org.bigbluebutton.api.model.validator; + +import org.apache.http.entity.ContentType; +import org.bigbluebutton.api.model.constraint.ContentTypeConstraint; +import org.bigbluebutton.api.model.request.Request; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +public class ContentTypeValidator implements ConstraintValidator { + + private static final Logger log = LoggerFactory.getLogger(ContentTypeValidator.class); + + @Override + public void initialize(ContentTypeConstraint constraintAnnotation) {} + + @Override + public boolean isValid(Request request, ConstraintValidatorContext context) { + HttpServletRequest servletRequest = request.getServletRequest(); + String requestMethod = servletRequest.getMethod(); + String contentType = servletRequest.getContentType(); + String contentTypeHeader = servletRequest.getHeader("Content-Type"); + log.info("Validating {} request with content type {}", requestMethod, contentType); + + boolean requestBodyPresent = servletRequest.getContentLength() > 0; + if (requestBodyPresent) { + if (contentType == null || contentTypeHeader == null) return false; + else { + try { + ContentType c = ContentType.parse(contentType); + String mimeType = c.getMimeType(); + for (Object o: request.getSupportedContentTypes()) { + String supportedContentType = (String) o; + if (mimeType.equalsIgnoreCase(supportedContentType)) return true; + } + } catch (Exception e) { + return false; + } + return false; + } + } + + return true; + } +} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/GetChecksumValidator.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/GetChecksumValidator.java index 0e439c7263..1395348ba0 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/GetChecksumValidator.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/GetChecksumValidator.java @@ -1,8 +1,10 @@ package org.bigbluebutton.api.model.validator; +import javax.servlet.http.HttpServletRequest; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; +import jakarta.ws.rs.core.MediaType; import org.apache.commons.codec.digest.DigestUtils; import org.bigbluebutton.api.model.constraint.GetChecksumConstraint; import org.bigbluebutton.api.model.shared.GetChecksum; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/PostChecksumValidator.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/PostChecksumValidator.java deleted file mode 100755 index b34a178197..0000000000 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/model/validator/PostChecksumValidator.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.bigbluebutton.api.model.validator; - -import org.apache.commons.codec.digest.DigestUtils; -import org.bigbluebutton.api.model.constraint.PostChecksumConstraint; -import org.bigbluebutton.api.model.shared.PostChecksum; -import org.bigbluebutton.api.service.ServiceUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; - -public class PostChecksumValidator implements ConstraintValidator { - - private static Logger log = LoggerFactory.getLogger(PostChecksumValidator.class); - - @Override - public void initialize(PostChecksumConstraint constraintAnnotation) {} - - @Override - public boolean isValid(PostChecksum checksum, ConstraintValidatorContext context) { - String securitySalt = ServiceUtils.getValidationService().getSecuritySalt(); - - if (securitySalt.isEmpty()) { - log.warn("Security is disabled in this service. Make sure this is intentional."); - return true; - } - - String queryStringWithoutChecksum = checksum.getQueryStringWithoutChecksum(); - log.info("query string after checksum removed: [{}]", queryStringWithoutChecksum); - - if(queryStringWithoutChecksum == null) { - return false; - } - - String providedChecksum = checksum.getChecksum(); - log.info("CHECKSUM={} length={}", providedChecksum, providedChecksum.length()); - - if(providedChecksum == null) { - return false; - } - - String data = checksum.getApiCall() + queryStringWithoutChecksum + securitySalt; - String createdCheckSum = DigestUtils.sha1Hex(data); - - if (createdCheckSum == null || !createdCheckSum.equalsIgnoreCase(providedChecksum)) { - log.info("checksumError: failed checksum. our checksum: [{}], client: [{}]", createdCheckSum, providedChecksum); - return false; - } - - return true; - } -} diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/pub/IPublisherService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/pub/IPublisherService.java index 55b7e0d107..27b782a7f3 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/pub/IPublisherService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/pub/IPublisherService.java @@ -22,7 +22,7 @@ public interface IPublisherService { void endMeeting(String meetingId); void send(String channel, String message); void registerUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, - String authToken, String avatarURL, Boolean guest, Boolean excludeFromDashboard, + String authToken, String avatarURL, String webcamBackgroundURL, Boolean guest, Boolean excludeFromDashboard, String enforceLayout, Boolean authed); void sendKeepAlive(String system, Long bbbWebTimestamp, Long akkaAppsTimestamp); void sendStunTurnInfo(String meetingId, String internalUserId, Set stuns, Set turns); diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/service/ValidationService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/service/ValidationService.java index b26b367adb..48c26ec213 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/service/ValidationService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/service/ValidationService.java @@ -4,11 +4,11 @@ import org.bigbluebutton.api.model.request.*; import org.bigbluebutton.api.model.shared.Checksum; import org.bigbluebutton.api.model.shared.ChecksumValidationGroup; import org.bigbluebutton.api.model.shared.GetChecksum; -import org.bigbluebutton.api.model.shared.PostChecksum; import org.bigbluebutton.api.util.ParamsUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.servlet.http.HttpServletRequest; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; @@ -39,12 +39,13 @@ public class ValidationService { GET_MEETINGS("getMeetings", RequestType.GET), GET_SESSIONS("getSessions", RequestType.GET), GUEST_WAIT("guestWait", RequestType.GET), - ENTER("enter", RequestType.GET), STUNS("stuns", RequestType.GET), SIGN_OUT("signOut", RequestType.GET), LEARNING_DASHBOARD("learningDashboard", RequestType.GET), GET_JOIN_URL("getJoinUrl", RequestType.GET), - INSERT_DOCUMENT("insertDocument", RequestType.GET); + FEEDBACK("feedback", RequestType.GET), + INSERT_DOCUMENT("insertDocument", RequestType.GET), + SEND_CHAT_MESSAGE("sendChatMessage", RequestType.GET); private final String name; private final RequestType requestType; @@ -70,11 +71,13 @@ public class ValidationService { validator = validatorFactory.getValidator(); } - public Map validate(ApiCall apiCall, Map params, String queryString) { + public Map validate(ApiCall apiCall, HttpServletRequest servletRequest) { + String queryString = servletRequest.getQueryString(); + Map params = servletRequest.getParameterMap(); log.info("Validating {} request with query string {}", apiCall.getName(), queryString); params = sanitizeParams(params); - Request request = initializeRequest(apiCall, params, queryString); + Request request = initializeRequest(apiCall, params, queryString, servletRequest); Map violations = new HashMap<>(); if(request == null) { @@ -101,7 +104,7 @@ public class ValidationService { } } - private Request initializeRequest(ApiCall apiCall, Map params, String queryString) { + private Request initializeRequest(ApiCall apiCall, Map params, String queryString, HttpServletRequest servletRequest) { Request request = null; Checksum checksum; @@ -110,55 +113,24 @@ public class ValidationService { checksumValue = params.get("checksum")[0]; } - if(queryString == null || queryString.isEmpty()) { - queryString = buildQueryStringFromParamsMap(params); - } - - switch(apiCall.requestType) { - case GET: - checksum = new GetChecksum(apiCall.getName(), checksumValue, queryString); - switch(apiCall) { - case CREATE: - request = new CreateMeeting(checksum); - break; - case JOIN: - request = new JoinMeeting(checksum); - break; - case MEETING_RUNNING: - request = new MeetingRunning(checksum); - break; - case END: - request = new EndMeeting(checksum); - break; - case GET_MEETING_INFO: - request = new MeetingInfo(checksum); - break; - case GET_MEETINGS: - case GET_SESSIONS: - request = new SimpleRequest(checksum); - break; - case INSERT_DOCUMENT: - request = new InsertDocument(checksum); - break; - case GUEST_WAIT: - request = new GuestWait(); - break; - case ENTER: - request = new Enter(); - break; - case STUNS: - request = new Stuns(); - break; - case SIGN_OUT: - request = new SignOut(); - break; - case LEARNING_DASHBOARD: - request = new LearningDashboard(); - break; - case GET_JOIN_URL: - request = new GetJoinUrl(); - break; - } + if (Objects.requireNonNull(apiCall.requestType) == RequestType.GET) { + checksum = new GetChecksum(apiCall.getName(), checksumValue, queryString, servletRequest); + request = switch (apiCall) { + case CREATE -> new CreateMeeting(checksum, servletRequest); + case JOIN -> new JoinMeeting(checksum, servletRequest); + case MEETING_RUNNING -> new MeetingRunning(checksum, servletRequest); + case END -> new EndMeeting(checksum, servletRequest); + case GET_MEETING_INFO -> new MeetingInfo(checksum, servletRequest); + case GET_MEETINGS, GET_SESSIONS -> new SimpleRequest(checksum, servletRequest); + case INSERT_DOCUMENT -> new InsertDocument(checksum, servletRequest); + case SEND_CHAT_MESSAGE -> new SendChatMessage(checksum, servletRequest); + case GUEST_WAIT -> new GuestWait(servletRequest); + case STUNS -> new Stuns(servletRequest); + case SIGN_OUT -> new SignOut(servletRequest); + case LEARNING_DASHBOARD -> new LearningDashboard(servletRequest); + case GET_JOIN_URL -> new GetJoinUrl(servletRequest); + case FEEDBACK -> new Feedback(servletRequest); + }; } return request; diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ResponseBuilder.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ResponseBuilder.java index e7a7a7a32c..11e5904c1c 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ResponseBuilder.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ResponseBuilder.java @@ -52,7 +52,7 @@ public class ResponseBuilder { return new Date(timestamp).toString(); } - public String buildMeetingVersion(String apiVersion, String bbbVersion, String graphqlWebsocketUrl, String returnCode) { + public String buildMeetingVersion(String apiVersion, String bbbVersion, String graphqlWebsocketUrl, String graphqlApiUrl, String returnCode) { StringWriter xmlText = new StringWriter(); Map data = new HashMap(); @@ -61,6 +61,7 @@ public class ResponseBuilder { data.put("apiVersion", apiVersion); data.put("bbbVersion", bbbVersion); data.put("graphqlWebsocketUrl", graphqlWebsocketUrl); + data.put("graphqlApiUrl", graphqlApiUrl); processData(getTemplate("api-version.ftlx"), data, xmlText); @@ -242,6 +243,19 @@ public class ResponseBuilder { return ftl; } + public String buildSendChatMessageResponse(String message, String returnCode) { + + StringWriter xmlText = new StringWriter(); + + Map data = new HashMap(); + data.put("returnCode", returnCode); + data.put("message", message); + + processData(getTemplate("send-chat-message.ftlx"), data, xmlText); + + return xmlText.toString(); + } + private void processData(Template template, Map data, StringWriter out) { try { template.process(data, out); diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java index dd16fc56fc..3c8bf97d4e 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IBbbWebApiGWApp.java @@ -11,6 +11,7 @@ import org.bigbluebutton.api.messaging.converters.messages.EndMeetingMessage; import org.bigbluebutton.api.messaging.converters.messages.PublishedRecordingMessage; import org.bigbluebutton.api.messaging.converters.messages.UnpublishedRecordingMessage; import org.bigbluebutton.api.messaging.converters.messages.DeletedRecordingMessage; +import org.bigbluebutton.api.messaging.messages.ChatMessageFromApi; import org.bigbluebutton.presentation.messages.IDocConversionMsg; public interface IBbbWebApiGWApp { @@ -24,10 +25,26 @@ public interface IBbbWebApiGWApp { Integer meetingCameraCap, Integer userCameraCap, Integer maxPinnedCameras, - String moderatorPass, String viewerPass, String learningDashboardAccessToken, Long createTime, - String createDate, Boolean isBreakout, Integer sequence, Boolean freejoin, Map metadata, - String guestPolicy, Boolean authenticatedGuest, Boolean allowPromoteGuestToModerator, String meetingLayout, String welcomeMsgTemplate, String welcomeMsg, String modOnlyMessage, - String dialNumber, Integer maxUsers, Integer maxUserConcurrentAccesses, + String moderatorPass, + String viewerPass, + String learningDashboardAccessToken, + Long createTime, + String createDate, + Boolean isBreakout, + Integer sequence, + Boolean freejoin, + Map metadata, + String guestPolicy, + Boolean authenticatedGuest, + Boolean allowPromoteGuestToModerator, + Long waitingGuestUsersTimeout, + String meetingLayout, + String welcomeMsgTemplate, + String welcomeMsg, + String welcomeMsgForModerators, + String dialNumber, + Integer maxUsers, + Integer maxUserConcurrentAccesses, Integer meetingExpireIfNoUserJoinedInMinutes, Integer meetingExpireWhenLastUserLeftInMinutes, Integer userInactivityInspectTimerInMinutes, @@ -44,6 +61,7 @@ public interface IBbbWebApiGWApp { String loginUrl, String logoutUrl, String customLogoURL, + String customDarkLogoURL, String bannerText, String bannerColor, ArrayList groups, @@ -54,10 +72,9 @@ public interface IBbbWebApiGWApp { String overrideClientSettings); void registerUser(String meetingID, String internalUserId, String fullname, String role, - String externUserID, String authToken, String sessionToken, String avatarURL, + String externUserID, String authToken, String sessionToken, String avatarURL, String webcamBackgroundURL, Boolean guest, Boolean authed, String guestStatus, Boolean excludeFromDashboard, - String enforceLayout, Map customParameters); - void guestWaitingLeft(String meetingID, String internalUserId); + String enforceLayout, Map userMetadata); void destroyMeeting(DestroyMeetingMessage msg); void endMeeting(EndMeetingMessage msg); @@ -66,4 +83,5 @@ public interface IBbbWebApiGWApp { void unpublishedRecording(UnpublishedRecordingMessage msg); void deletedRecording(DeletedRecordingMessage msg); void sendDocConversionMsg(IDocConversionMsg msg); + void sendChatMessage(ChatMessageFromApi msg); } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IMeetingService.java b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IMeetingService.java index 15817fbb0f..def05fcff9 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api2/IMeetingService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api2/IMeetingService.java @@ -15,7 +15,7 @@ public interface IMeetingService { void addUserSession(String token, UserSession user); void registerUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, - String authToken, String avatarURL, Boolean guest, Boolean authed); + String authToken, String avatarURL, String webcamBackgroundURL, Boolean guest, Boolean authed); UserSession getUserSession(String token); UserSession removeUserSession(String token); void purgeRegisteredUsers(); diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/Meeting2.java b/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/Meeting2.java index 9811b8ac39..fa5c562523 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/Meeting2.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/Meeting2.java @@ -17,6 +17,7 @@ public class Meeting2 { public final boolean forciblyEnded; public final String logoutUrl; public final String defaultAvatarURL; + public final String defaultWebcamBackgroundURL; public final Map metadata; public final List breakoutRooms; @@ -30,6 +31,7 @@ public class Meeting2 { boolean forciblyEnded, String logoutUrl, String defaultAvatarURL, + String defaultWebcamBackgroundURL, Map metadata, List breakoutRooms) { this.props = props; @@ -42,6 +44,7 @@ public class Meeting2 { this.forciblyEnded = forciblyEnded; this.logoutUrl = logoutUrl; this.defaultAvatarURL = defaultAvatarURL; + this.defaultWebcamBackgroundURL = defaultWebcamBackgroundURL; this.metadata = metadata; this.breakoutRooms = breakoutRooms; } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/WelcomeProp2.java b/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/WelcomeProp2.java index fd7b6884cd..3bd44cded7 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/WelcomeProp2.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api2/domain/WelcomeProp2.java @@ -1,15 +1,13 @@ package org.bigbluebutton.api2.domain; public class WelcomeProp2 { - public final String welcomeMsgTemplate; public final String welcomeMsg; - public final String modOnlyMessage; + public final String welcomeMsgForModerators; public WelcomeProp2(String welcomeMsgTemplate, String welcomeMsg, - String modOnlyMessage) { - this.welcomeMsgTemplate = welcomeMsgTemplate; + String welcomeMsgForModerators) { this.welcomeMsg = welcomeMsg; - this.modOnlyMessage = modOnlyMessage; + this.welcomeMsgForModerators = welcomeMsgForModerators; } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/FileTypeConstants.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/FileTypeConstants.java index 832db0120b..dcba94307e 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/FileTypeConstants.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/FileTypeConstants.java @@ -32,12 +32,14 @@ public final class FileTypeConstants { public static final String TXT = "txt"; public static final String ODS = "ods"; public static final String ODP = "odp"; + public static final String ODG = "odg"; public static final String AVI = "avi"; public static final String MPG = "mpg"; public static final String MP3 = "mp3"; public static final String PDF = "pdf"; public static final String JPG = "jpg"; public static final String JPEG = "jpeg"; + public static final String WEBP = "webp"; public static final String PNG = "png"; public static final String SVG = "svg"; private FileTypeConstants() {} // Prevent instantiation diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/MimeTypeUtils.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/MimeTypeUtils.java index d6bd667890..82198c334b 100644 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/MimeTypeUtils.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/MimeTypeUtils.java @@ -19,12 +19,17 @@ public class MimeTypeUtils { private static final String RTF = "application/rtf"; private static final String TXT = "text/plain"; private static final String ODS = "application/vnd.oasis.opendocument.spreadsheet"; + private static final String ODG = "application/vnd.oasis.opendocument.graphics"; private static final String ODP = "application/vnd.oasis.opendocument.presentation"; private static final String PDF = "application/pdf"; private static final String JPEG = "image/jpeg"; private static final String PNG = "image/png"; private static final String SVG = "image/svg+xml"; + private static final String WEBP = "image/webp"; + // If the following mime-types are changed, please, make sure to also change: + // bigbluebutton-html5/private/config/settings.yml: L827 + // docs/docs/development/api.md: L1222 private static final HashMap> EXTENSIONS_MIME = new HashMap>(16) { { put(FileTypeConstants.DOC, Arrays.asList(DOC, DOCX, TIKA_MSOFFICE, TIKA_MSOFFICE_X)); @@ -34,6 +39,7 @@ public class MimeTypeUtils { put(FileTypeConstants.PPTX, Arrays.asList(PPT, PPTX, TIKA_MSOFFICE, TIKA_MSOFFICE_X)); put(FileTypeConstants.XLSX, Arrays.asList(XLS, XLSX, TIKA_MSOFFICE, TIKA_MSOFFICE_X)); put(FileTypeConstants.ODT, Arrays.asList(ODT)); + put(FileTypeConstants.ODG, Arrays.asList(ODG)); put(FileTypeConstants.RTF, Arrays.asList(RTF)); put(FileTypeConstants.TXT, Arrays.asList(TXT)); put(FileTypeConstants.ODS, Arrays.asList(ODS)); @@ -43,6 +49,7 @@ public class MimeTypeUtils { put(FileTypeConstants.JPEG, Arrays.asList(JPEG)); put(FileTypeConstants.PNG, Arrays.asList(PNG)); put(FileTypeConstants.SVG, Arrays.asList(SVG)); + put(FileTypeConstants.WEBP, Arrays.asList(WEBP)); } }; @@ -71,8 +78,9 @@ public class MimeTypeUtils { public List getValidMimeTypes() { List validMimeTypes = Arrays.asList(XLS, XLSX, - DOC, DOCX, PPT, PPTX, ODT, RTF, TXT, ODS, ODP, - PDF, JPEG, PNG, SVG, TIKA_MSOFFICE, TIKA_MSOFFICE_X + DOC, DOCX, PPT, PPTX, ODT, RTF, TXT, ODS, ODP, ODG, + PDF, JPEG, PNG, SVG, TIKA_MSOFFICE, TIKA_MSOFFICE_X, + WEBP ); return validMimeTypes; } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java index 6fe5e1014f..9add5bb657 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/PresentationUrlDownloadService.java @@ -94,6 +94,7 @@ public class PresentationUrlDownloadService { }, 5, TimeUnit.SECONDS); } + // A negative presentationSlide indicates the entire presentation deck should be used. private void extractPage(final String sourceMeetingId, final String presentationId, final Integer presentationSlide, final String destinationMeetingId) { @@ -146,7 +147,7 @@ public class PresentationUrlDownloadService { + newFilename; File newPresentation = new File(newFilePath); - if (sourcePresentationFile.getName().toLowerCase().endsWith("pdf")) { + if (sourcePresentationFile.getName().toLowerCase().endsWith("pdf") && presentationSlide >= 0) { pageExtractor.extractPage(sourcePresentationFile, new File( newFilePath), presentationSlide); } else { diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedDocumentFilter.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedDocumentFilter.java index f566a99839..85ceed5fea 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedDocumentFilter.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedDocumentFilter.java @@ -40,7 +40,7 @@ public class SupportedDocumentFilter { /* Get file extension - Perhaps try to rely on a more accurate method than an extension type ? */ String extension = FilenameUtils.getExtension(presentationFile.getName()); - boolean supported = SupportedFileTypes.isFileSupported(extension); + boolean supported = SupportedFileTypes.isPresentationMimeTypeValid(presentationFile, extension); notifyProgressListener(supported, pres); if (supported) { log.info("Received supported file {}", pres.getUploadedFile().getAbsolutePath()); diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedFileTypes.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedFileTypes.java index 4e68969451..f15017ed67 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedFileTypes.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/SupportedFileTypes.java @@ -38,37 +38,21 @@ public final class SupportedFileTypes { private static Logger log = LoggerFactory.getLogger(SupportedFileTypes.class); private static MimeTypeUtils mimeTypeUtils = new MimeTypeUtils(); - - private static final List SUPPORTED_FILE_LIST = Collections.unmodifiableList(new ArrayList(15) { - { - // Add all the supported files - add(XLS); add(XLSX); add(DOC); add(DOCX); add(PPT); add(PPTX); - add(ODT); add(RTF); add(TXT); add(ODS); add(ODP); add(PDF); - add(JPG); add(JPEG); add(PNG); - } - }); private static final List OFFICE_FILE_LIST = Collections.unmodifiableList(new ArrayList(11) { { // Add all Offile file types add(XLS); add(XLSX); add(DOC); add(DOCX); add(PPT); add(PPTX); - add(ODT); add(RTF); add(TXT); add(ODS); add(ODP); + add(ODT); add(RTF); add(TXT); add(ODS); add(ODP); add(ODG); } }); private static final List IMAGE_FILE_LIST = Collections.unmodifiableList(new ArrayList(3) { { // Add all image file types - add(JPEG); add(JPG); add(PNG); + add(JPEG); add(JPG); add(PNG); add(WEBP); add(SVG); } }); - - /* - * Returns if the file with extension is supported. - */ - public static boolean isFileSupported(String fileExtension) { - return SUPPORTED_FILE_LIST.contains(fileExtension.toLowerCase()); - } /* * Returns if the Office file is supported. diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/WaitingGuestCleanupTimerTask.java b/bbb-common-web/src/main/java/org/bigbluebutton/web/services/WaitingGuestCleanupTimerTask.java deleted file mode 100755 index bb94828387..0000000000 --- a/bbb-common-web/src/main/java/org/bigbluebutton/web/services/WaitingGuestCleanupTimerTask.java +++ /dev/null @@ -1,56 +0,0 @@ -/** -* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ -* -* Copyright (c) 2020 BigBlueButton Inc. and by respective authors (see below). -* -* This program is free software; you can redistribute it and/or modify it under the -* terms of the GNU Lesser General Public License as published by the Free Software -* Foundation; either version 3.0 of the License, or (at your option) any later -* version. -* -* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License along -* with BigBlueButton; if not, see . -* -*/ - -package org.bigbluebutton.web.services; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import org.bigbluebutton.api.MeetingService; - -public class WaitingGuestCleanupTimerTask { - - private MeetingService service; - private ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1); - private long runEvery = 15000; - - public void setMeetingService(MeetingService svc) { - this.service = svc; - } - - public void start() { - scheduledThreadPool.scheduleWithFixedDelay(new CleanupTask(), 60000, runEvery, TimeUnit.MILLISECONDS); - } - - public void stop() { - scheduledThreadPool.shutdownNow(); - } - - public void setRunEvery(long v) { - runEvery = v; - } - - private class CleanupTask implements Runnable { - @Override - public void run() { - service.purgeWaitingGuestUsers(); - } - } -} diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala index 1330c33862..a21444e9e8 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/BbbWebApiGWApp.scala @@ -5,6 +5,7 @@ import org.apache.pekko.actor.ActorSystem import org.apache.pekko.event.Logging import org.bigbluebutton.api.domain.{BreakoutRoomsParams, Group, LockSettingsParams} import org.bigbluebutton.api.messaging.converters.messages._ +import org.bigbluebutton.api.messaging.messages.ChatMessageFromApi import org.bigbluebutton.api2.bus._ import org.bigbluebutton.api2.endpoint.redis.WebRedisSubscriberActor import org.bigbluebutton.common2.redis.MessageSender @@ -130,9 +131,13 @@ class BbbWebApiGWApp( createTime: java.lang.Long, createDate: String, isBreakout: java.lang.Boolean, sequence: java.lang.Integer, freeJoin: java.lang.Boolean, - metadata: java.util.Map[String, String], guestPolicy: String, authenticatedGuest: java.lang.Boolean, allowPromoteGuestToModerator: java.lang.Boolean, - meetingLayout: String, - welcomeMsgTemplate: String, welcomeMsg: String, modOnlyMessage: String, + metadata: java.util.Map[String, String], + guestPolicy: String, + authenticatedGuest: java.lang.Boolean, + allowPromoteGuestToModerator: java.lang.Boolean, + waitingGuestUsersTimeout: java.lang.Long, + meetingLayout: String, + welcomeMsgTemplate: String, welcomeMsg: String, welcomeMsgForModerators: String, dialNumber: String, maxUsers: java.lang.Integer, maxUserConcurrentAccesses: java.lang.Integer, @@ -152,6 +157,7 @@ class BbbWebApiGWApp( loginUrl: String, logoutUrl: String, customLogoURL: String, + customDarkLogoURL: String, bannerText: String, bannerColor: String, groups: java.util.ArrayList[Group], @@ -207,8 +213,7 @@ class BbbWebApiGWApp( captureSlidesFilename = breakoutParams.captureSlidesFilename, ) - val welcomeProp = WelcomeProp(welcomeMsgTemplate = welcomeMsgTemplate, welcomeMsg = welcomeMsg, - modOnlyMessage = modOnlyMessage) + val welcomeProp = WelcomeProp(welcomeMsg = welcomeMsg, welcomeMsgForModerators = welcomeMsgForModerators) val voiceProp = VoiceProp(telVoice = voiceBridge, voiceConf = voiceBridge, dialNumber = dialNumber, muteOnStart = muteOnStart.booleanValue()) val usersProp = UsersProp( maxUsers = maxUsers.intValue(), @@ -218,7 +223,8 @@ class BbbWebApiGWApp( guestPolicy = guestPolicy, meetingLayout = meetingLayout, allowModsToUnmuteUsers = allowModsToUnmuteUsers.booleanValue(), allowModsToEjectCameras = allowModsToEjectCameras.booleanValue(), authenticatedGuest = authenticatedGuest.booleanValue(), - allowPromoteGuestToModerator = allowPromoteGuestToModerator.booleanValue() + allowPromoteGuestToModerator = allowPromoteGuestToModerator.booleanValue(), + waitingGuestUsersTimeout = waitingGuestUsersTimeout.longValue() ) val metadataProp = MetadataProp(mapAsScalaMap(metadata).toMap) @@ -242,6 +248,7 @@ class BbbWebApiGWApp( }, logoutUrl, customLogoURL, + customDarkLogoURL, bannerText match { case t: String => t case _ => "" @@ -279,9 +286,9 @@ class BbbWebApiGWApp( def registerUser(meetingId: String, intUserId: String, name: String, role: String, extUserId: String, authToken: String, sessionToken: String, - avatarURL: String, guest: java.lang.Boolean, authed: java.lang.Boolean, + avatarURL: String, webcamBackgroundURL: String, guest: java.lang.Boolean, authed: java.lang.Boolean, guestStatus: String, excludeFromDashboard: java.lang.Boolean, - enforceLayout: String, customParameters: java.util.Map[String, String]): Unit = { + enforceLayout: String, userMetadata: java.util.Map[String, String]): Unit = { // meetingManagerActorRef ! new RegisterUser(meetingId = meetingId, intUserId = intUserId, name = name, // role = role, extUserId = extUserId, authToken = authToken, avatarURL = avatarURL, @@ -289,19 +296,14 @@ class BbbWebApiGWApp( val regUser = new RegisterUser(meetingId = meetingId, intUserId = intUserId, name = name, role = role, extUserId = extUserId, authToken = authToken, sessionToken = sessionToken, - avatarURL = avatarURL, guest = guest.booleanValue(), authed = authed.booleanValue(), + avatarURL = avatarURL, webcamBackgroundURL = webcamBackgroundURL, guest = guest.booleanValue(), authed = authed.booleanValue(), guestStatus = guestStatus, excludeFromDashboard = excludeFromDashboard, enforceLayout = enforceLayout, - customParameters = (customParameters).asScala.toMap) + userMetadata = (userMetadata).asScala.toMap) val event = MsgBuilder.buildRegisterUserRequestToAkkaApps(regUser) msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) } - def guestWaitingLeft(meetingId: String, intUserId: String): Unit = { - val event = MsgBuilder.buildGuestWaitingLeftMsg(meetingId, intUserId) - msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) - } - def destroyMeeting(msg: DestroyMeetingMessage): Unit = { val event = MsgBuilder.buildDestroyMeetingSysCmdMsg(msg) msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) @@ -381,6 +383,13 @@ class BbbWebApiGWApp( } } + def sendChatMessage(msg: ChatMessageFromApi): Unit ={ + if (msg.isInstanceOf[ChatMessageFromApi]){ + val event = MsgBuilder.buildSendChatMessageFromApi(msg.asInstanceOf[ChatMessageFromApi]) + msgToAkkaAppsEventBus.publish(MsgToAkkaApps(toAkkaAppsChannel, event)) + } + } + /*** Caption API ***/ def generateSingleUseCaptionToken(recordId: String, caption: String, expirySeconds: Long): String = { redisStorage.generateSingleUseCaptionToken(recordId, caption, expirySeconds) diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala index 2464c57fa1..5b672e48eb 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/MsgBuilder.scala @@ -1,6 +1,7 @@ package org.bigbluebutton.api2 import org.bigbluebutton.api.messaging.converters.messages._ +import org.bigbluebutton.api.messaging.messages.ChatMessageFromApi import org.bigbluebutton.api2.meeting.RegisterUser import org.bigbluebutton.common2.domain.{ DefaultProps, PageVO, PresentationPageConvertedVO, PresentationVO } import org.bigbluebutton.common2.msgs._ @@ -49,21 +50,12 @@ object MsgBuilder { val header = BbbCoreHeaderWithMeetingId(RegisterUserReqMsg.NAME, msg.meetingId) val body = RegisterUserReqMsgBody(meetingId = msg.meetingId, intUserId = msg.intUserId, name = msg.name, role = msg.role, extUserId = msg.extUserId, authToken = msg.authToken, sessionToken = msg.sessionToken, - avatarURL = msg.avatarURL, guest = msg.guest, authed = msg.authed, guestStatus = msg.guestStatus, - excludeFromDashboard = msg.excludeFromDashboard, enforceLayout = msg.enforceLayout, customParameters = msg.customParameters) + avatarURL = msg.avatarURL, webcamBackgroundURL = msg.webcamBackgroundURL, guest = msg.guest, authed = msg.authed, guestStatus = msg.guestStatus, + excludeFromDashboard = msg.excludeFromDashboard, enforceLayout = msg.enforceLayout, userMetadata = msg.userMetadata) val req = RegisterUserReqMsg(header, body) BbbCommonEnvCoreMsg(envelope, req) } - def buildGuestWaitingLeftMsg(meetingId: String, userId: String): BbbCommonEnvCoreMsg = { - val routing = collection.immutable.HashMap("sender" -> "bbb-web") - val envelope = BbbCoreEnvelope(GuestWaitingLeftMsg.NAME, routing) - val header = BbbClientMsgHeader(GuestWaitingLeftMsg.NAME, meetingId, "not-used") - val body = GuestWaitingLeftMsgBody(userId) - val req = GuestWaitingLeftMsg(header, body) - BbbCommonEnvCoreMsg(envelope, req) - } - def buildCheckAlivePingSysMsg(system: String, bbbWebTimestamp: Long, akkaAppsTimestamp: Long): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-web") val envelope = BbbCoreEnvelope(CheckAlivePingSysMsg.NAME, routing) @@ -359,6 +351,19 @@ object MsgBuilder { BbbCommonEnvCoreMsg(envelope, req) } + def buildSendChatMessageFromApi(msg: ChatMessageFromApi): BbbCommonEnvCoreMsg = { + val routing = collection.immutable.HashMap("sender" -> "bbb-web") + val envelope = BbbCoreEnvelope(SendGroupChatMessageFromApiSysPubMsg.NAME, routing) + val header = BbbClientMsgHeader(SendGroupChatMessageFromApiSysPubMsg.NAME, msg.meetingId, "not-used") + + val body = SendGroupChatMessageFromApiSysPubMsgBody( + userName = msg.name, message = msg.message + ) + + val req = SendGroupChatMessageFromApiSysPubMsg(header, body) + BbbCommonEnvCoreMsg(envelope, req) + } + def buildPresentationUploadedFileTimedoutErrorSysMsg(msg: UploadFileTimedoutMessage): BbbCommonEnvCoreMsg = { val routing = collection.immutable.HashMap("sender" -> "bbb-web") val envelope = BbbCoreEnvelope(PresentationUploadedFileTimeoutErrorSysPubMsg.NAME, routing) diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala index e62435f351..1017fd84c2 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/bus/ReceivedJsonMsgHdlrActor.scala @@ -66,8 +66,6 @@ class ReceivedJsonMsgHdlrActor(val msgFromAkkaAppsEventBus: MsgFromAkkaAppsEvent route[MeetingDestroyedEvtMsg](envelope, jsonNode) case CheckAlivePongSysMsg.NAME => route[CheckAlivePongSysMsg](envelope, jsonNode) - case UserEmojiChangedEvtMsg.NAME => - route[UserEmojiChangedEvtMsg](envelope, jsonNode) case PresenterUnassignedEvtMsg.NAME => route[PresenterUnassignedEvtMsg](envelope, jsonNode) case PresenterAssignedEvtMsg.NAME => diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/domain/User2.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/domain/User2.scala index 4d9e029e5b..8aca491e62 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/domain/User2.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/domain/User2.scala @@ -3,7 +3,7 @@ package org.bigbluebutton.api2.domain case class CallerId(name: String, number: String) case class VoiceUser(id: String, callerId: CallerId, status: String, vid: String, wid: String, callingWith: String) -case class User2(intId: String, extId: String, name: String, role: String, avatarURL: String, +case class User2(intId: String, extId: String, name: String, role: String, avatarURL: String, webcamBackgroundURL: String, guest: Boolean, waitingForAcceptance: Boolean, status: Vector[String], streams: Set[String], customData: UserCustomData, voiceUser: VoiceUser, webcamStreams: Vector[String]) @@ -39,7 +39,7 @@ class Users { } case class RegisteredUser2(meetingId: String, intId: String, name: String, role: String, - extId: String, authToken: String, avatarURL: String, + extId: String, authToken: String, avatarURL: String, webcamBackgroundURL: String, guest: Boolean, authed: Boolean) object RegisteredUsers { diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/MeetingsManagerActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/MeetingsManagerActor.scala index 2b17a8006d..a883b2f2df 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/MeetingsManagerActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/MeetingsManagerActor.scala @@ -16,9 +16,9 @@ case class CreateBreakoutRoomMsg(meetingId: String, parentMeetingId: String, case class AddUserSession(token: String, session: UserSession) case class RegisterUser(meetingId: String, intUserId: String, name: String, role: String, - extUserId: String, authToken: String, sessionToken: String, avatarURL: String, + extUserId: String, authToken: String, sessionToken: String, avatarURL: String, webcamBackgroundURL: String, guest: Boolean, authed: Boolean, guestStatus: String, excludeFromDashboard: Boolean, - enforceLayout: String, customParameters: Map[String, String]) + enforceLayout: String, userMetadata: Map[String, String]) case class CreateMeetingMsg(defaultProps: DefaultProps) diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala index 9603058fc8..66f1501b41 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/OldMeetingMsgHdlrActor.scala @@ -24,7 +24,6 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW) case m: MeetingEndedEvtMsg => handleMeetingEndedEvtMsg(m) case m: MeetingDestroyedEvtMsg => handleMeetingDestroyedEvtMsg(m) case m: CheckAlivePongSysMsg => handleCheckAlivePongSysMsg(m) - case m: UserEmojiChangedEvtMsg => handleUserEmojiChangedEvtMsg(m) case m: PresenterUnassignedEvtMsg => handlePresenterUnassignedEvtMsg(m) case m: PresenterAssignedEvtMsg => handlePresenterAssignedEvtMsg(m) case m: UserJoinedMeetingEvtMsg => handleUserJoinedMeetingEvtMsg(m) @@ -143,7 +142,7 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW) def handleUserJoinedMeetingEvtMsg(msg: UserJoinedMeetingEvtMsg): Unit = { olgMsgGW.handle(new UserJoined(msg.header.meetingId, msg.body.intId, - msg.body.extId, msg.body.name, msg.body.role, msg.body.locked, msg.body.avatar, + msg.body.extId, msg.body.name, msg.body.role, msg.body.locked, msg.body.avatar, msg.body.webcamBackground, msg.body.guest, msg.body.guestStatus, msg.body.clientType)) } @@ -155,10 +154,6 @@ class OldMeetingMsgHdlrActor(val olgMsgGW: OldMessageReceivedGW) olgMsgGW.handle(new UserStatusChanged(msg.header.meetingId, msg.body.presenterId, "presenter", "true")) } - def handleUserEmojiChangedEvtMsg(msg: UserEmojiChangedEvtMsg): Unit = { - //listener.handle(new UserStatusChanged(meetingId, userid, status, value)) - } - def handleUserLeftMeetingEvtMsg(msg: UserLeftMeetingEvtMsg): Unit = { olgMsgGW.handle(new UserLeft(msg.header.meetingId, msg.body.intId)) } diff --git a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/ToAkkaAppsSendersTrait.scala b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/ToAkkaAppsSendersTrait.scala index 7f11d06304..5b32026ac4 100755 --- a/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/ToAkkaAppsSendersTrait.scala +++ b/bbb-common-web/src/main/scala/org/bigbluebutton/api2/meeting/ToAkkaAppsSendersTrait.scala @@ -28,9 +28,9 @@ trait ToAkkaAppsSendersTrait extends SystemConfiguration { val header = BbbCoreHeaderWithMeetingId(RegisterUserReqMsg.NAME, msg.meetingId) val body = RegisterUserReqMsgBody(meetingId = msg.meetingId, intUserId = msg.intUserId, name = msg.name, role = msg.role, extUserId = msg.extUserId, authToken = msg.authToken, - sessionToken = msg.sessionToken, avatarURL = msg.avatarURL, guest = msg.guest, authed = msg.authed, + sessionToken = msg.sessionToken, avatarURL = msg.avatarURL, webcamBackgroundURL = msg.webcamBackgroundURL, guest = msg.guest, authed = msg.authed, guestStatus = msg.guestStatus, excludeFromDashboard = msg.excludeFromDashboard, - enforceLayout = msg.enforceLayout, customParameters = msg.customParameters) + enforceLayout = msg.enforceLayout, userMetadata = msg.userMetadata) val req = RegisterUserReqMsg(header, body) val message = BbbCommonEnvCoreMsg(envelope, req) sendToBus(message) diff --git a/bbb-common-web/src/test/resources/send-chat-message.ftlx b/bbb-common-web/src/test/resources/send-chat-message.ftlx new file mode 100644 index 0000000000..657b7f0c10 --- /dev/null +++ b/bbb-common-web/src/test/resources/send-chat-message.ftlx @@ -0,0 +1,8 @@ +<#ftl output_format="XML" auto_esc=true> +<#compress> + + <#-- Where code is a 'SUCCESS' or 'FAILED' String --> + ${returnCode} + ${message} + + \ No newline at end of file diff --git a/bbb-export-annotations/package-lock.json b/bbb-export-annotations/package-lock.json index 454bc9af42..8da20a3338 100644 --- a/bbb-export-annotations/package-lock.json +++ b/bbb-export-annotations/package-lock.json @@ -1,7 +1,7 @@ { "name": "bbb-export-annotations", "version": "2.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -9,7 +9,7 @@ "version": "2.0", "dependencies": { "@svgdotjs/svg.js": "^3.2.0", - "axios": "^1.6.5", + "axios": "^1.7.4", "form-data": "^4.0.0", "opentype.js": "^1.3.4", "perfect-freehand": "^1.0.16", @@ -27,16 +27,43 @@ "npm": ">=9.5.0" } }, - "node_modules/@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -45,151 +72,188 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, + "license": "MIT", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.0" + "node": ">=12.22" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" }, - "node_modules/@node-redis/bloom": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@node-redis/bloom/-/bloom-1.0.1.tgz", - "integrity": "sha512-mXEBvEIgF4tUzdIN89LiYsbi6//EdpFA7L8M+DHCvePXg+bfHWi+ct5VI6nHUFQE5+ohm/9wmgihCH3HSkeKsw==", - "peerDependencies": { - "@node-redis/client": "^1.0.0" + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@node-redis/client": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@node-redis/client/-/client-1.0.3.tgz", - "integrity": "sha512-IXNgOG99PHGL3NxN3/e8J8MuX+H08I+OMNmheGmZBXngE0IntaCQwwrd7NzmiHA+zH3SKHiJ+6k3P7t7XYknMw==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", "dependencies": { - "cluster-key-slot": "1.1.0", - "generic-pool": "3.8.2", - "redis-parser": "3.0.0", + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@redis/bloom": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", + "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", + "license": "MIT", + "peerDependencies": { + "@redis/client": "^1.0.0" + } + }, + "node_modules/@redis/client": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz", + "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==", + "license": "MIT", + "dependencies": { + "cluster-key-slot": "1.1.2", + "generic-pool": "3.9.0", "yallist": "4.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, - "node_modules/@node-redis/graph": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@node-redis/graph/-/graph-1.0.0.tgz", - "integrity": "sha512-mRSo8jEGC0cf+Rm7q8mWMKKKqkn6EAnA9IA2S3JvUv/gaWW/73vil7GLNwion2ihTptAm05I9LkepzfIXUKX5g==", + "node_modules/@redis/graph": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", + "license": "MIT", "peerDependencies": { - "@node-redis/client": "^1.0.0" + "@redis/client": "^1.0.0" } }, - "node_modules/@node-redis/json": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@node-redis/json/-/json-1.0.2.tgz", - "integrity": "sha512-qVRgn8WfG46QQ08CghSbY4VhHFgaTY71WjpwRBGEuqGPfWwfRcIf3OqSpR7Q/45X+v3xd8mvYjywqh0wqJ8T+g==", + "node_modules/@redis/json": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz", + "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==", + "license": "MIT", "peerDependencies": { - "@node-redis/client": "^1.0.0" + "@redis/client": "^1.0.0" } }, - "node_modules/@node-redis/search": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@node-redis/search/-/search-1.0.2.tgz", - "integrity": "sha512-gWhEeji+kTAvzZeguUNJdMSZNH2c5dv3Bci8Nn2f7VGuf6IvvwuZDSBOuOlirLVgayVuWzAG7EhwaZWK1VDnWQ==", + "node_modules/@redis/search": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz", + "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==", + "license": "MIT", "peerDependencies": { - "@node-redis/client": "^1.0.0" + "@redis/client": "^1.0.0" } }, - "node_modules/@node-redis/time-series": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@node-redis/time-series/-/time-series-1.0.1.tgz", - "integrity": "sha512-+nTn6EewVj3GlUXPuD3dgheWqo219jTxlo6R+pg24OeVvFHx9aFGGiyOgj3vBPhWUdRZ0xMcujXV5ki4fbLyMw==", + "node_modules/@redis/time-series": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz", + "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==", + "license": "MIT", "peerDependencies": { - "@node-redis/client": "^1.0.0" + "@redis/client": "^1.0.0" } }, "node_modules/@svgdotjs/svg.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.0.tgz", - "integrity": "sha512-Tr8p+QVP7y+QT1GBlq1Tt57IvedVH8zCPoYxdHLX0Oof3a/PqnC/tXAkVufv1JQJfsDHlH/UrjcDfgxSofqSNA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.4.tgz", + "integrity": "sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/Fuzzyma" } }, "node_modules/@swc/helpers": { - "version": "0.4.36", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.36.tgz", - "integrity": "sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", + "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "license": "Apache-2.0", "dependencies": { - "legacy-swc-helpers": "npm:@swc/helpers@=0.4.14", "tslib": "^2.4.0" } }, - "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true, + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -202,6 +266,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -211,6 +276,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -227,6 +293,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -236,6 +303,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -250,17 +318,20 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -271,7 +342,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", @@ -290,13 +362,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -306,6 +380,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", + "license": "MIT", "dependencies": { "base64-js": "^1.1.2" } @@ -315,6 +390,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -324,6 +400,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -339,14 +416,16 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", "engines": { "node": ">=0.8" } }, "node_modules/cluster-key-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", - "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", "engines": { "node": ">=0.10.0" } @@ -356,6 +435,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -367,12 +447,14 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -384,13 +466,15 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -401,23 +485,35 @@ } }, "node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "license": "MIT", "dependencies": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -425,13 +521,15 @@ "node_modules/dfa": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", - "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==" + "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==", + "license": "MIT" }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -444,6 +542,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -452,46 +551,50 @@ } }, "node_modules/eslint": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", - "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -508,6 +611,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=0.10.0" }, @@ -516,96 +620,59 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.7.1", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -618,6 +685,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -630,6 +698,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -639,6 +708,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -646,25 +716,39 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -672,13 +756,32 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.1.0", + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { @@ -686,21 +789,23 @@ } }, "node_modules/flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", - "dev": true + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -711,11 +816,12 @@ } }, "node_modules/fontkit": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.2.tgz", - "integrity": "sha512-jc4k5Yr8iov8QfS6u8w2CnHWVmbOGtdBtOXMze5Y+QD966Rx6PEVWXSEGwXlsDlKtu1G12cJjcsybnqhSk/+LA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.4.tgz", + "integrity": "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==", + "license": "MIT", "dependencies": { - "@swc/helpers": "^0.4.2", + "@swc/helpers": "^0.5.12", "brotli": "^1.3.2", "clone": "^2.1.2", "dfa": "^1.2.0", @@ -730,6 +836,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -743,18 +850,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/generic-pool": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.8.2.tgz", - "integrity": "sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", + "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", + "license": "MIT", "engines": { "node": ">= 4" } @@ -763,7 +866,9 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -784,6 +889,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -792,10 +898,11 @@ } }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -806,11 +913,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -819,6 +934,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -827,10 +943,11 @@ } }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -839,6 +956,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "license": "MIT", "dependencies": { "queue": "6.0.2" }, @@ -854,6 +972,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -870,6 +989,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -878,7 +998,9 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -887,13 +1009,15 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -903,6 +1027,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -910,17 +1035,29 @@ "node": ">=0.10.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -928,25 +1065,35 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/legacy-swc-helpers": { - "name": "@swc/helpers", - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", - "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.4.0" + "json-buffer": "3.0.1" } }, "node_modules/levn": { @@ -954,6 +1101,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -962,25 +1110,44 @@ "node": ">= 0.8.0" } }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" }, "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -991,6 +1158,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -999,20 +1167,23 @@ } }, "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/needle": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "license": "MIT", "dependencies": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -1025,11 +1196,21 @@ "node": ">= 4.4.x" } }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -1038,6 +1219,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz", "integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==", + "license": "MIT", "dependencies": { "string.prototype.codepointat": "^0.2.1", "tiny-inflate": "^1.0.3" @@ -1050,32 +1232,67 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "license": "MIT" }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -1083,11 +1300,22 @@ "node": ">=6" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1097,20 +1325,23 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/perfect-freehand": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/perfect-freehand/-/perfect-freehand-1.0.16.tgz", - "integrity": "sha512-D4+avUeR8CHSl2vaPbPYX/dNpSMRYO3VOFp7qSSc+LRkSgzQbLATVnXosy7VxtsSHEh1C5t8K8sfmo0zCVnfWQ==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/perfect-freehand/-/perfect-freehand-1.2.2.tgz", + "integrity": "sha512-eh31l019WICQ03pkF3FSzHxB8n07ItqIQ++G5UV8JX0zVOXzgTGCqnRR0jJ2h9U8/2uW4W4mtGJELt9kEV0CFQ==", + "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -1119,6 +1350,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.2.3.tgz", "integrity": "sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==", + "license": "MIT", "dependencies": { "lodash.merge": "^4.6.2", "needle": "^2.5.2", @@ -1128,13 +1360,15 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1143,52 +1377,47 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "license": "MIT", "dependencies": { "inherits": "~2.0.3" } }, - "node_modules/redis": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.0.3.tgz", - "integrity": "sha512-SJMRXvgiQUYN0HaWwWv002J5ZgkhYXOlbLomzcrL3kP42yRNZ8Jx5nvLYhVpgmf10xcDpanFOxxJkphu2eyIFQ==", - "dependencies": { - "@node-redis/bloom": "1.0.1", - "@node-redis/client": "1.0.3", - "@node-redis/graph": "1.0.0", - "@node-redis/json": "1.0.2", - "@node-redis/search": "1.0.2", - "@node-redis/time-series": "1.0.1" - } - }, - "node_modules/redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=", - "engines": { - "node": ">=4" - } - }, - "node_modules/redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", - "dependencies": { - "redis-errors": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/redis": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz", + "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==", + "license": "MIT", + "workspaces": [ + "./packages/*" + ], + "dependencies": { + "@redis/bloom": "1.2.0", + "@redis/client": "1.6.0", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.7", + "@redis/search": "1.2.0", + "@redis/time-series": "1.1.0" } }, "node_modules/resolve-from": { @@ -1196,20 +1425,35 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/restructure": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.1.tgz", - "integrity": "sha512-6neDpI/yE9eogQo22qmWwKIA9wFPRyYjQleDEh6zaNAf2ZPqLJYUvNBJBWEWNoBlCeQMQkvIOe2YI/K2GOag+g==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz", + "integrity": "sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==", + "license": "MIT" + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -1220,29 +1464,57 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/sanitize-filename": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "license": "WTFPL OR ISC", "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -1255,6 +1527,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1262,7 +1535,8 @@ "node_modules/stream-parser": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", - "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=", + "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==", + "license": "MIT", "dependencies": { "debug": "2" } @@ -1271,6 +1545,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -1278,18 +1553,21 @@ "node_modules/stream-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/string.prototype.codepointat": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", - "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==", + "license": "MIT" }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1302,6 +1580,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -1314,6 +1593,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -1325,6 +1605,7 @@ "version": "0.1.19", "resolved": "https://registry.npmjs.org/svgdom/-/svgdom-0.1.19.tgz", "integrity": "sha512-gBvlZ74RECaG9VyPrj9OdakOarEKKvaXh5NVkbx9oWfAo4XnQehk75b14iOW2UjFHyZThczZ1NrPV9rDrecOVg==", + "license": "MIT", "dependencies": { "fontkit": "^2.0.2", "image-size": "^1.0.2", @@ -1339,31 +1620,36 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tiny-inflate": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", - "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "license": "WTFPL", "dependencies": { "utf8-byte-length": "^1.0.1" } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -1376,6 +1662,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -1387,6 +1674,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz", "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==", + "license": "MIT", "dependencies": { "base64-js": "^1.3.0", "unicode-trie": "^2.0.0" @@ -1396,6 +1684,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "license": "MIT", "dependencies": { "pako": "^0.2.5", "tiny-inflate": "^1.0.0" @@ -1406,26 +1695,23 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/utf8-byte-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=" - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", + "license": "(WTFPL OR MIT)" }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -1437,10 +1723,11 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1449,1110 +1736,27 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - }, - "dependencies": { - "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "license": "MIT", + "engines": { + "node": ">=10" }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } - }, - "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@node-redis/bloom": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@node-redis/bloom/-/bloom-1.0.1.tgz", - "integrity": "sha512-mXEBvEIgF4tUzdIN89LiYsbi6//EdpFA7L8M+DHCvePXg+bfHWi+ct5VI6nHUFQE5+ohm/9wmgihCH3HSkeKsw==", - "requires": {} - }, - "@node-redis/client": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@node-redis/client/-/client-1.0.3.tgz", - "integrity": "sha512-IXNgOG99PHGL3NxN3/e8J8MuX+H08I+OMNmheGmZBXngE0IntaCQwwrd7NzmiHA+zH3SKHiJ+6k3P7t7XYknMw==", - "requires": { - "cluster-key-slot": "1.1.0", - "generic-pool": "3.8.2", - "redis-parser": "3.0.0", - "yallist": "4.0.0" - } - }, - "@node-redis/graph": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@node-redis/graph/-/graph-1.0.0.tgz", - "integrity": "sha512-mRSo8jEGC0cf+Rm7q8mWMKKKqkn6EAnA9IA2S3JvUv/gaWW/73vil7GLNwion2ihTptAm05I9LkepzfIXUKX5g==", - "requires": {} - }, - "@node-redis/json": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@node-redis/json/-/json-1.0.2.tgz", - "integrity": "sha512-qVRgn8WfG46QQ08CghSbY4VhHFgaTY71WjpwRBGEuqGPfWwfRcIf3OqSpR7Q/45X+v3xd8mvYjywqh0wqJ8T+g==", - "requires": {} - }, - "@node-redis/search": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@node-redis/search/-/search-1.0.2.tgz", - "integrity": "sha512-gWhEeji+kTAvzZeguUNJdMSZNH2c5dv3Bci8Nn2f7VGuf6IvvwuZDSBOuOlirLVgayVuWzAG7EhwaZWK1VDnWQ==", - "requires": {} - }, - "@node-redis/time-series": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@node-redis/time-series/-/time-series-1.0.1.tgz", - "integrity": "sha512-+nTn6EewVj3GlUXPuD3dgheWqo219jTxlo6R+pg24OeVvFHx9aFGGiyOgj3vBPhWUdRZ0xMcujXV5ki4fbLyMw==", - "requires": {} - }, - "@svgdotjs/svg.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.0.tgz", - "integrity": "sha512-Tr8p+QVP7y+QT1GBlq1Tt57IvedVH8zCPoYxdHLX0Oof3a/PqnC/tXAkVufv1JQJfsDHlH/UrjcDfgxSofqSNA==" - }, - "@swc/helpers": { - "version": "0.4.36", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.36.tgz", - "integrity": "sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q==", - "requires": { - "legacy-swc-helpers": "npm:@swc/helpers@=0.4.14", - "tslib": "^2.4.0" - } - }, - "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", - "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brotli": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", - "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", - "requires": { - "base64-js": "^1.1.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" - }, - "cluster-key-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", - "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==" - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "dfa": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dfa/-/dfa-1.2.0.tgz", - "integrity": "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==" - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz", - "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "eslint-config-google": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", - "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", - "dev": true, - "requires": {} - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", - "dev": true, - "requires": { - "acorn": "^8.7.1", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz", - "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" - }, - "fontkit": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fontkit/-/fontkit-2.0.2.tgz", - "integrity": "sha512-jc4k5Yr8iov8QfS6u8w2CnHWVmbOGtdBtOXMze5Y+QD966Rx6PEVWXSEGwXlsDlKtu1G12cJjcsybnqhSk/+LA==", - "requires": { - "@swc/helpers": "^0.4.2", - "brotli": "^1.3.2", - "clone": "^2.1.2", - "dfa": "^1.2.0", - "fast-deep-equal": "^3.1.3", - "restructure": "^3.0.0", - "tiny-inflate": "^1.0.3", - "unicode-properties": "^1.4.0", - "unicode-trie": "^2.0.0" - } - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "generic-pool": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.8.2.tgz", - "integrity": "sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg==" - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "image-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", - "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", - "requires": { - "queue": "6.0.2" - } - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "legacy-swc-helpers": { - "version": "npm:@swc/helpers@0.4.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", - "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", - "requires": { - "tslib": "^2.4.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "requires": { - "mime-db": "1.51.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "needle": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", - "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opentype.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz", - "integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==", - "requires": { - "string.prototype.codepointat": "^0.2.1", - "tiny-inflate": "^1.0.3" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "perfect-freehand": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/perfect-freehand/-/perfect-freehand-1.0.16.tgz", - "integrity": "sha512-D4+avUeR8CHSl2vaPbPYX/dNpSMRYO3VOFp7qSSc+LRkSgzQbLATVnXosy7VxtsSHEh1C5t8K8sfmo0zCVnfWQ==" - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "probe-image-size": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-7.2.3.tgz", - "integrity": "sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==", - "requires": { - "lodash.merge": "^4.6.2", - "needle": "^2.5.2", - "stream-parser": "~0.3.1" - } - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "requires": { - "inherits": "~2.0.3" - } - }, - "redis": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.0.3.tgz", - "integrity": "sha512-SJMRXvgiQUYN0HaWwWv002J5ZgkhYXOlbLomzcrL3kP42yRNZ8Jx5nvLYhVpgmf10xcDpanFOxxJkphu2eyIFQ==", - "requires": { - "@node-redis/bloom": "1.0.1", - "@node-redis/client": "1.0.3", - "@node-redis/graph": "1.0.0", - "@node-redis/json": "1.0.2", - "@node-redis/search": "1.0.2", - "@node-redis/time-series": "1.0.1" - } - }, - "redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=" - }, - "redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=", - "requires": { - "redis-errors": "^1.0.0" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "restructure": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.1.tgz", - "integrity": "sha512-6neDpI/yE9eogQo22qmWwKIA9wFPRyYjQleDEh6zaNAf2ZPqLJYUvNBJBWEWNoBlCeQMQkvIOe2YI/K2GOag+g==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sanitize-filename": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", - "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", - "requires": { - "truncate-utf8-bytes": "^1.0.0" - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "stream-parser": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", - "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=", - "requires": { - "debug": "2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "string.prototype.codepointat": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", - "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "svgdom": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/svgdom/-/svgdom-0.1.19.tgz", - "integrity": "sha512-gBvlZ74RECaG9VyPrj9OdakOarEKKvaXh5NVkbx9oWfAo4XnQehk75b14iOW2UjFHyZThczZ1NrPV9rDrecOVg==", - "requires": { - "fontkit": "^2.0.2", - "image-size": "^1.0.2", - "sax": "^1.2.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "tiny-inflate": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", - "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" - }, - "truncate-utf8-bytes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", - "requires": { - "utf8-byte-length": "^1.0.1" - } - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "unicode-properties": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz", - "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==", - "requires": { - "base64-js": "^1.3.0", - "unicode-trie": "^2.0.0" - } - }, - "unicode-trie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", - "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", - "requires": { - "pako": "^0.2.5", - "tiny-inflate": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "utf8-byte-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } } diff --git a/bbb-export-annotations/package.json b/bbb-export-annotations/package.json index 90f35bf9b2..5108cd1b1b 100644 --- a/bbb-export-annotations/package.json +++ b/bbb-export-annotations/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@svgdotjs/svg.js": "^3.2.0", - "axios": "^1.6.5", + "axios": "^1.7.4", "form-data": "^4.0.0", "opentype.js": "^1.3.4", "perfect-freehand": "^1.0.16", diff --git a/bbb-graphql-actions/deploy.sh b/bbb-graphql-actions/deploy.sh index 0190ba913c..1f18a5ef7a 100755 --- a/bbb-graphql-actions/deploy.sh +++ b/bbb-graphql-actions/deploy.sh @@ -1,9 +1,4 @@ #!/usr/bin/env bash -if [ "$EUID" -ne 0 ]; then - echo "Please run this script as root ( or with sudo )" ; - exit 1; -fi; - cd "$(dirname "$0")" @@ -11,15 +6,15 @@ for var in "$@" do if [[ $var == --reset ]] ; then echo "Performing a full reset..." - rm -rf node_modules + sudo rm -rf node_modules fi done if [ ! -d ./node_modules ] ; then - npm ci --no-progress + sudo npm ci --no-progress fi -npm run build +sudo npm run build # handle renaming circa dec 2023 if [[ -d /usr/local/bigbluebutton/bbb-graphql-actions-adapter-server ]] ; then @@ -29,7 +24,7 @@ if [[ -d /usr/local/bigbluebutton/bbb-graphql-actions-adapter-server ]] ; then sudo rm -rf /usr/local/bigbluebutton/bbb-graphql-actions-adapter-server fi -mv -f dist/index.js dist/bbb-graphql-actions.js +sudo mv -f dist/index.js dist/bbb-graphql-actions.js sudo cp -rf dist/* /usr/local/bigbluebutton/bbb-graphql-actions sudo systemctl restart bbb-graphql-actions echo '' diff --git a/bbb-graphql-actions/package-lock.json b/bbb-graphql-actions/package-lock.json index 38e0a22ffd..1362b70603 100644 --- a/bbb-graphql-actions/package-lock.json +++ b/bbb-graphql-actions/package-lock.json @@ -12,7 +12,7 @@ "@types/express": "^4.17.18", "@types/node": "^20.7.0", "@types/redis": "^4.0.11", - "axios": "^1.6.0", + "axios": "^1.7.4", "express": "^4.19.2", "redis": "^4.6.10" }, @@ -27,6 +27,7 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -35,25 +36,28 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -63,14 +67,16 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", + "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/client": { - "version": "1.5.11", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.11.tgz", - "integrity": "sha512-cV7yHcOAtNQ5x/yQl7Yw1xf53kO0FNDTdDU6bFIMbW6ljB7U7ns0YRM+QIkpoqTAt6zK5k9Fq0QWlUbLcq9AvA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz", + "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==", + "license": "MIT", "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -81,82 +87,93 @@ } }, "node_modules/@redis/graph": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz", - "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", + "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", + "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/json": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", - "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz", + "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==", + "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/search": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.5.tgz", - "integrity": "sha512-hPP8w7GfGsbtYEJdn4n7nXa6xt6hVZnnDktKW4ArMaFQ/m/aR7eFvsLQmG/mn1Upq99btPJk+F27IQ2dYpCoUg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz", + "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==", + "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz", + "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==", + "license": "MIT", "peerDependencies": { "@redis/client": "^1.0.0" } }, "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/body-parser": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.3.tgz", - "integrity": "sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/connect": { - "version": "3.4.36", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", - "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/express": { - "version": "4.17.18", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", - "integrity": "sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -165,9 +182,10 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.37", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz", - "integrity": "sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==", + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -176,68 +194,74 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", - "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "license": "MIT" }, "node_modules/@types/mime": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz", - "integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" }, "node_modules/@types/node": { - "version": "20.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", - "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" + "version": "20.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", + "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } }, "node_modules/@types/qs": { - "version": "6.9.8", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", - "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==" + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "license": "MIT" }, "node_modules/@types/range-parser": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.5.tgz", - "integrity": "sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" }, "node_modules/@types/redis": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/@types/redis/-/redis-4.0.11.tgz", "integrity": "sha512-bI+gth8La8Wg/QCR1+V1fhrL9+LZUSWfcqpOj2Kc80ZQ4ffbdL173vQd5wovmoV9i071FU9oP2g6etLuEwb6Rg==", "deprecated": "This is a stub types definition. redis provides its own type definitions, so you do not need this installed.", + "license": "MIT", "dependencies": { "redis": "*" } }, "node_modules/@types/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", - "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", - "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "license": "MIT", "dependencies": { "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" + "@types/node": "*", + "@types/send": "*" } }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -247,10 +271,11 @@ } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -259,10 +284,14 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -272,6 +301,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -284,24 +314,28 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", - "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -310,21 +344,27 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -349,18 +389,20 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -370,6 +412,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -378,6 +421,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -393,16 +437,11 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -415,6 +454,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -423,6 +465,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", "engines": { "node": ">=0.10.0" } @@ -431,6 +474,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -442,12 +486,14 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -459,6 +505,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -467,6 +514,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -474,18 +522,21 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -494,6 +545,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -510,6 +562,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -518,6 +571,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -526,6 +580,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -536,6 +591,7 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -543,12 +599,14 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -557,6 +615,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -568,6 +627,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -575,12 +635,14 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -589,6 +651,7 @@ "version": "4.19.2", "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -627,10 +690,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -642,6 +706,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -656,15 +721,16 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -678,6 +744,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -691,6 +758,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -699,6 +767,7 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -709,6 +778,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -721,6 +791,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -729,6 +800,7 @@ "version": "3.9.0", "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", + "license": "MIT", "engines": { "node": ">= 4" } @@ -737,6 +809,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -756,6 +829,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -767,6 +841,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -779,6 +854,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -787,6 +863,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -798,6 +875,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -809,6 +887,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -820,6 +899,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -831,6 +911,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -846,6 +927,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -857,17 +939,20 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -877,6 +962,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -889,6 +975,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -898,6 +985,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -910,32 +998,23 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -943,12 +1022,14 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "license": "MIT" }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -957,6 +1038,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -968,6 +1050,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -976,6 +1059,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -988,6 +1072,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -998,24 +1083,27 @@ "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/nodemon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", - "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", + "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": "^3.5.2", - "debug": "^3.2.7", + "debug": "^4", "ignore-by-default": "^1.0.1", "minimatch": "^3.1.2", "pstree.remy": "^1.1.8", @@ -1037,48 +1125,48 @@ } }, "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/nodemon/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1087,6 +1175,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -1098,6 +1187,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1105,13 +1195,15 @@ "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "license": "MIT" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -1123,6 +1215,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -1134,18 +1227,21 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -1160,6 +1256,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1168,6 +1265,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -1183,6 +1281,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -1191,16 +1290,20 @@ } }, "node_modules/redis": { - "version": "4.6.10", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.10.tgz", - "integrity": "sha512-mmbyhuKgDiJ5TWUhiKhBssz+mjsuSI/lSZNPI9QvZOYzWvYGejtb+W3RlDDf8LD6Bdl5/mZeG8O1feUGhXTxEg==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz", + "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==", + "license": "MIT", + "workspaces": [ + "./packages/*" + ], "dependencies": { "@redis/bloom": "1.2.0", - "@redis/client": "1.5.11", - "@redis/graph": "1.1.0", - "@redis/json": "1.0.6", - "@redis/search": "1.1.5", - "@redis/time-series": "1.0.5" + "@redis/client": "1.6.0", + "@redis/graph": "1.1.1", + "@redis/json": "1.0.7", + "@redis/search": "1.2.0", + "@redis/time-series": "1.1.0" } }, "node_modules/safe-buffer": { @@ -1220,21 +1323,21 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -1246,6 +1349,7 @@ "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -1268,12 +1372,14 @@ "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -1288,6 +1394,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -1303,12 +1410,14 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -1327,6 +1436,7 @@ "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -1338,6 +1448,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1347,6 +1458,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -1359,6 +1471,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -1370,27 +1483,27 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, + "license": "ISC", "bin": { "nodetouch": "bin/nodetouch.js" } }, "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -1433,6 +1546,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -1442,10 +1556,11 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1458,12 +1573,20 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1472,6 +1595,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -1480,12 +1604,14 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1493,13 +1619,15 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } diff --git a/bbb-graphql-actions/package.json b/bbb-graphql-actions/package.json index 2b01a5d782..d7001d0339 100644 --- a/bbb-graphql-actions/package.json +++ b/bbb-graphql-actions/package.json @@ -1,5 +1,6 @@ { "name": "bbb-graphql-actions", + "homepage": "/html5client/", "version": "0.0.1", "description": "A server component designed to interface between Hasura GraphQL actions and BigBlueButton ecosystem.", "main": "index.ts", @@ -27,7 +28,7 @@ "@types/express": "^4.17.18", "@types/node": "^20.7.0", "@types/redis": "^4.0.11", - "axios": "^1.6.0", + "axios": "^1.7.4", "express": "^4.19.2", "redis": "^4.6.10" }, diff --git a/bbb-graphql-actions/src/actions/allUsersClearReaction.ts b/bbb-graphql-actions/src/actions/allUsersClearReaction.ts index bda7dc25f1..16c6fc3ff4 100644 --- a/bbb-graphql-actions/src/actions/allUsersClearReaction.ts +++ b/bbb-graphql-actions/src/actions/allUsersClearReaction.ts @@ -3,6 +3,7 @@ import {throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + const eventName = `ClearAllUsersReactionCmdMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/breakoutRoomCreate.ts b/bbb-graphql-actions/src/actions/breakoutRoomCreate.ts index 8294fc3d3e..ec972383ae 100644 --- a/bbb-graphql-actions/src/actions/breakoutRoomCreate.ts +++ b/bbb-graphql-actions/src/actions/breakoutRoomCreate.ts @@ -1,10 +1,41 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; +import {ValidationError} from "../types/ValidationError"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); const eventName = 'CreateBreakoutRoomsCmdMsg'; + throwErrorIfInvalidInput(input, + [ + {name: 'record', type: 'boolean', required: true}, + {name: 'captureNotes', type: 'boolean', required: true}, + {name: 'captureSlides', type: 'boolean', required: true}, + {name: 'durationInMinutes', type: 'int', required: true}, + {name: 'sendInviteToModerators', type: 'boolean', required: true}, + {name: 'rooms', type: 'objectArray', required: true}, + ] + ) + + const breakoutRooms = input['rooms'] as Array>; + if(breakoutRooms.length < 2) { + throw new ValidationError('It is required to set two or more rooms.', 400); + } + + throwErrorIfInvalidInput(breakoutRooms[0], + [ + {name: 'captureNotesFilename', type: 'string', required: true}, + {name: 'captureSlidesFilename', type: 'string', required: true}, + {name: 'freeJoin', type: 'boolean', required: true}, + {name: 'isDefaultName', type: 'boolean', required: true}, + {name: 'name', type: 'string', required: true}, + {name: 'sequence', type: 'int', required: true}, + {name: 'shortName', type: 'string', required: true}, + {name: 'users', type: 'stringArray', required: true}, + ] + ) + + const routing = { meetingId: sessionVariables['x-hasura-meetingid'] as String, userId: sessionVariables['x-hasura-userid'] as String diff --git a/bbb-graphql-actions/src/actions/breakoutRoomEndAll.ts b/bbb-graphql-actions/src/actions/breakoutRoomEndAll.ts index 9cc50fd4a7..f42716ef01 100644 --- a/bbb-graphql-actions/src/actions/breakoutRoomEndAll.ts +++ b/bbb-graphql-actions/src/actions/breakoutRoomEndAll.ts @@ -3,6 +3,7 @@ import {throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + const eventName = 'EndAllBreakoutRoomsMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/breakoutRoomMoveUser.ts b/bbb-graphql-actions/src/actions/breakoutRoomMoveUser.ts index 511bae45fa..0a40deeac3 100644 --- a/bbb-graphql-actions/src/actions/breakoutRoomMoveUser.ts +++ b/bbb-graphql-actions/src/actions/breakoutRoomMoveUser.ts @@ -1,8 +1,17 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: true}, + {name: 'fromBreakoutRoomId', type: 'string', required: true}, + {name: 'toBreakoutRoomId', type: 'string', required: true}, + ] + ) + const eventName = 'ChangeUserBreakoutReqMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/breakoutRoomRequestJoinUrl.ts b/bbb-graphql-actions/src/actions/breakoutRoomRequestJoinUrl.ts index 5d6361afb2..9ee13c7226 100644 --- a/bbb-graphql-actions/src/actions/breakoutRoomRequestJoinUrl.ts +++ b/bbb-graphql-actions/src/actions/breakoutRoomRequestJoinUrl.ts @@ -1,8 +1,15 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { const eventName = 'RequestBreakoutJoinURLReqMsg'; + throwErrorIfInvalidInput(input, + [ + {name: 'breakoutRoomId', type: 'string', required: true}, + ] + ) + const routing = { meetingId: sessionVariables['x-hasura-meetingid'] as String, userId: sessionVariables['x-hasura-userid'] as String diff --git a/bbb-graphql-actions/src/actions/breakoutRoomSendMessageToAll.ts b/bbb-graphql-actions/src/actions/breakoutRoomSendMessageToAll.ts index 21c7f5a2a3..24fc7f169c 100644 --- a/bbb-graphql-actions/src/actions/breakoutRoomSendMessageToAll.ts +++ b/bbb-graphql-actions/src/actions/breakoutRoomSendMessageToAll.ts @@ -1,8 +1,15 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + + throwErrorIfInvalidInput(input, + [ + {name: 'message', type: 'string', required: true}, + ] + ) + const eventName = 'SendMessageToAllBreakoutRoomsReqMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/breakoutRoomSetInviteDismissed.ts b/bbb-graphql-actions/src/actions/breakoutRoomSetInviteDismissed.ts new file mode 100644 index 0000000000..1f245fc73c --- /dev/null +++ b/bbb-graphql-actions/src/actions/breakoutRoomSetInviteDismissed.ts @@ -0,0 +1,21 @@ +import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; + +export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + const eventName = `SetBreakoutRoomInviteDismissedReqMsg`; + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as String, + userId: sessionVariables['x-hasura-userid'] as String + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId + }; + + const body = {}; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/breakoutRoomSetTime.ts b/bbb-graphql-actions/src/actions/breakoutRoomSetTime.ts index b6610361b9..211efb7253 100644 --- a/bbb-graphql-actions/src/actions/breakoutRoomSetTime.ts +++ b/bbb-graphql-actions/src/actions/breakoutRoomSetTime.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'timeInMinutes', type: 'int', required: true}, + ] + ) + const eventName = 'UpdateBreakoutRoomsTimeReqMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/cameraBroadcastStart.ts b/bbb-graphql-actions/src/actions/cameraBroadcastStart.ts index 1cde21991f..e4b4d8cb36 100644 --- a/bbb-graphql-actions/src/actions/cameraBroadcastStart.ts +++ b/bbb-graphql-actions/src/actions/cameraBroadcastStart.ts @@ -1,6 +1,13 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'stream', type: 'string', required: true}, + ] + ) + const eventName = `UserBroadcastCamStartMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/cameraBroadcastStop.ts b/bbb-graphql-actions/src/actions/cameraBroadcastStop.ts index 5468ca9ae7..58b68d3f76 100644 --- a/bbb-graphql-actions/src/actions/cameraBroadcastStop.ts +++ b/bbb-graphql-actions/src/actions/cameraBroadcastStop.ts @@ -1,6 +1,13 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'stream', type: 'string', required: true}, + ] + ) + const eventName = `UserBroadcastCamStopMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/allUsersClearEmoji.ts b/bbb-graphql-actions/src/actions/captionAddLocale.ts similarity index 66% rename from bbb-graphql-actions/src/actions/allUsersClearEmoji.ts rename to bbb-graphql-actions/src/actions/captionAddLocale.ts index 2748cd48bb..aeefccf25e 100644 --- a/bbb-graphql-actions/src/actions/allUsersClearEmoji.ts +++ b/bbb-graphql-actions/src/actions/captionAddLocale.ts @@ -1,9 +1,16 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); - const eventName = `ClearAllUsersEmojiCmdMsg`; + + throwErrorIfInvalidInput(input, + [ + {name: 'locale', type: 'string', required: true}, + ] + ) + + const eventName = `AddCaptionLocalePubMsg`; const routing = { meetingId: sessionVariables['x-hasura-meetingid'] as String, @@ -17,7 +24,7 @@ export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'transcriptId', type: 'string', required: true}, + {name: 'start', type: 'int', required: true}, + {name: 'end', type: 'int', required: true}, + {name: 'text', type: 'string', required: true}, + {name: 'transcript', type: 'string', required: true}, + {name: 'locale', type: 'string', required: true}, + {name: 'isFinal', type: 'boolean', required: true}, + ] + ) + const eventName = `UpdateTranscriptPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/captionSubmitTranscript.ts b/bbb-graphql-actions/src/actions/captionSubmitTranscript.ts new file mode 100644 index 0000000000..85a0595c03 --- /dev/null +++ b/bbb-graphql-actions/src/actions/captionSubmitTranscript.ts @@ -0,0 +1,36 @@ + +import { throwErrorIfInvalidInput } from '../imports/validation'; +import { RedisMessage } from '../types'; + +export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + const eventName = `CaptionSubmitTranscriptPubMsg`; + + throwErrorIfInvalidInput(input, + [ + {name: 'transcriptId', type: 'string', required: true}, + {name: 'transcript', type: 'string', required: true}, + {name: 'locale', type: 'string', required: true}, + {name: 'captionType', type: 'string', required: true}, + ] +) + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as String, + userId: sessionVariables['x-hasura-userid'] as String + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId + }; + + const body = { + transcriptId: input.transcriptId, + transcript: input.transcript, + locale: input.locale, + captionType: input.captionType, + }; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/chatCreateWithUser.ts b/bbb-graphql-actions/src/actions/chatCreateWithUser.ts index b2b1cde5a1..53f3c5064e 100644 --- a/bbb-graphql-actions/src/actions/chatCreateWithUser.ts +++ b/bbb-graphql-actions/src/actions/chatCreateWithUser.ts @@ -1,6 +1,13 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: true}, + ] + ) + const eventName = `CreateGroupChatReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/chatPublicClearHistory.ts b/bbb-graphql-actions/src/actions/chatPublicClearHistory.ts index 0ad08f3ef3..f2694c8a0b 100644 --- a/bbb-graphql-actions/src/actions/chatPublicClearHistory.ts +++ b/bbb-graphql-actions/src/actions/chatPublicClearHistory.ts @@ -1,8 +1,9 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + const eventName = `ClearPublicChatHistoryPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/chatRemove.ts b/bbb-graphql-actions/src/actions/chatRemove.ts index 02781858bf..3dccb1478d 100644 --- a/bbb-graphql-actions/src/actions/chatRemove.ts +++ b/bbb-graphql-actions/src/actions/chatRemove.ts @@ -1,6 +1,13 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'chatId', type: 'string', required: true}, + ] + ) + const eventName = `DestroyGroupChatReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/chatSendMessage.ts b/bbb-graphql-actions/src/actions/chatSendMessage.ts index d6741cfc16..a5c48f31ca 100644 --- a/bbb-graphql-actions/src/actions/chatSendMessage.ts +++ b/bbb-graphql-actions/src/actions/chatSendMessage.ts @@ -1,8 +1,16 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { - const eventName = `SendGroupChatMessageMsg`; + throwErrorIfInvalidInput(input, + [ + {name: 'chatMessageInMarkdownFormat', type: 'string', required: true}, + {name: 'chatId', type: 'string', required: true}, + {name: 'metadata', type: 'json', required: false} + ] + ) + const eventName = `SendGroupChatMessageMsg`; const routing = { meetingId: sessionVariables['x-hasura-meetingid'] as String, userId: sessionVariables['x-hasura-userid'] as String @@ -22,7 +30,8 @@ export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'chatId', type: 'string', required: true}, + {name: 'lastSeenAt', type: 'string', required: true}, + ] + ) + + const eventName = `SetGroupChatLastSeenReqMsg`; + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as String, + userId: sessionVariables['x-hasura-userid'] as String + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId + }; + + const body = { + chatId: input.chatId, + lastSeenAt: input.lastSeenAt, + }; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/chatSetTyping.ts b/bbb-graphql-actions/src/actions/chatSetTyping.ts index 081e6e3ace..9e80704d5d 100644 --- a/bbb-graphql-actions/src/actions/chatSetTyping.ts +++ b/bbb-graphql-actions/src/actions/chatSetTyping.ts @@ -1,6 +1,13 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'chatId', type: 'string', required: true}, + ] + ) + const eventName = `UserTypingPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/chatSetVisible.ts b/bbb-graphql-actions/src/actions/chatSetVisible.ts new file mode 100644 index 0000000000..5d87faacb0 --- /dev/null +++ b/bbb-graphql-actions/src/actions/chatSetVisible.ts @@ -0,0 +1,31 @@ +import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; + +export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'chatId', type: 'string', required: true}, + {name: 'visible', type: 'boolean', required: true}, + ] + ) + + const eventName = `SetGroupChatVisibleReqMsg`; + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as String, + userId: sessionVariables['x-hasura-userid'] as String + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId + }; + + const body = { + chatId: input.chatId, + visible: input.visible, + }; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/externalVideoStart.ts b/bbb-graphql-actions/src/actions/externalVideoStart.ts index 0cd41e3710..e3c5131577 100644 --- a/bbb-graphql-actions/src/actions/externalVideoStart.ts +++ b/bbb-graphql-actions/src/actions/externalVideoStart.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'externalVideoUrl', type: 'string', required: true}, + ] + ) + const eventName = `StartExternalVideoPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/externalVideoStop.ts b/bbb-graphql-actions/src/actions/externalVideoStop.ts index 788026846e..de27e0d78e 100644 --- a/bbb-graphql-actions/src/actions/externalVideoStop.ts +++ b/bbb-graphql-actions/src/actions/externalVideoStop.ts @@ -3,6 +3,7 @@ import {throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + const eventName = `StopExternalVideoPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/externalVideoUpdate.ts b/bbb-graphql-actions/src/actions/externalVideoUpdate.ts index e9e475a8d5..2f8c6a92e6 100644 --- a/bbb-graphql-actions/src/actions/externalVideoUpdate.ts +++ b/bbb-graphql-actions/src/actions/externalVideoUpdate.ts @@ -1,8 +1,17 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'status', type: 'string', required: true}, + {name: 'rate', type: 'number', required: true}, + {name: 'time', type: 'number', required: true}, + {name: 'state', type: 'number', required: true}, + ] + ) + const eventName = `UpdateExternalVideoPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/guestUsersSetLobbyMessage.ts b/bbb-graphql-actions/src/actions/guestUsersSetLobbyMessage.ts index 1d74aa9176..baa247a41d 100644 --- a/bbb-graphql-actions/src/actions/guestUsersSetLobbyMessage.ts +++ b/bbb-graphql-actions/src/actions/guestUsersSetLobbyMessage.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'message', type: 'string', required: true}, + ] + ) + const eventName = 'SetGuestLobbyMessageCmdMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/guestUsersSetLobbyMessagePrivate.ts b/bbb-graphql-actions/src/actions/guestUsersSetLobbyMessagePrivate.ts index 3a21f19d07..d9b53058e6 100644 --- a/bbb-graphql-actions/src/actions/guestUsersSetLobbyMessagePrivate.ts +++ b/bbb-graphql-actions/src/actions/guestUsersSetLobbyMessagePrivate.ts @@ -1,8 +1,15 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'guestId', type: 'string', required: true}, + {name: 'message', type: 'string', required: true}, + ] + ) + const eventName = 'SetPrivateGuestLobbyMessageCmdMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/guestUsersSetPolicy.ts b/bbb-graphql-actions/src/actions/guestUsersSetPolicy.ts index 1841db5d0a..754983b3a6 100644 --- a/bbb-graphql-actions/src/actions/guestUsersSetPolicy.ts +++ b/bbb-graphql-actions/src/actions/guestUsersSetPolicy.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'guestPolicy', type: 'string', required: true}, + ] + ) + const eventName = 'SetGuestPolicyCmdMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/guestUsersSubmitApprovalStatus.ts b/bbb-graphql-actions/src/actions/guestUsersSubmitApprovalStatus.ts index 8d46efffb5..14338cc211 100644 --- a/bbb-graphql-actions/src/actions/guestUsersSubmitApprovalStatus.ts +++ b/bbb-graphql-actions/src/actions/guestUsersSubmitApprovalStatus.ts @@ -1,8 +1,24 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'guests', type: 'objectArray', required: true}, + ] + ) + + const guests = input['guests'] as Array>; + if(guests.length > 0) { + throwErrorIfInvalidInput(guests[0], + [ + {name: 'guest', type: 'string', required: true}, + {name: 'status', type: 'string', required: true}, + ] + ) + } + const eventName = 'GuestsWaitingApprovedMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/meetingEnd.ts b/bbb-graphql-actions/src/actions/meetingEnd.ts index c527dedd95..03c5fcb6dc 100644 --- a/bbb-graphql-actions/src/actions/meetingEnd.ts +++ b/bbb-graphql-actions/src/actions/meetingEnd.ts @@ -3,6 +3,7 @@ import {throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + const eventName = 'LogoutAndEndMeetingCmdMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/meetingLayoutSetProps.ts b/bbb-graphql-actions/src/actions/meetingLayoutSetProps.ts index 9ed32008f4..af4a192456 100644 --- a/bbb-graphql-actions/src/actions/meetingLayoutSetProps.ts +++ b/bbb-graphql-actions/src/actions/meetingLayoutSetProps.ts @@ -1,8 +1,20 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'layout', type: 'string', required: true}, + {name: 'syncWithPresenterLayout', type: 'boolean', required: true}, + {name: 'presentationIsOpen', type: 'boolean', required: true}, + {name: 'isResizing', type: 'boolean', required: true}, + {name: 'cameraPosition', type: 'string', required: false}, + {name: 'focusedCamera', type: 'string', required: true}, + {name: 'presentationVideoRate', type: 'number', required: true}, + ] + ) + const eventName = 'BroadcastLayoutMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/meetingLayoutSetSyncWithPresenterLayout.ts b/bbb-graphql-actions/src/actions/meetingLayoutSetSyncWithPresenterLayout.ts index 0cecb31e2b..6d5f84b42b 100644 --- a/bbb-graphql-actions/src/actions/meetingLayoutSetSyncWithPresenterLayout.ts +++ b/bbb-graphql-actions/src/actions/meetingLayoutSetSyncWithPresenterLayout.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'syncWithPresenterLayout', type: 'boolean', required: true}, + ] + ) + const eventName = 'BroadcastPushLayoutMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/meetingLockSettingsSetProps.ts b/bbb-graphql-actions/src/actions/meetingLockSettingsSetProps.ts index bf8b9e2671..d9786e1aeb 100644 --- a/bbb-graphql-actions/src/actions/meetingLockSettingsSetProps.ts +++ b/bbb-graphql-actions/src/actions/meetingLockSettingsSetProps.ts @@ -1,8 +1,23 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'disableCam', type: 'boolean', required: true}, + {name: 'disableMic', type: 'boolean', required: true}, + {name: 'disablePrivChat', type: 'boolean', required: true}, + {name: 'disablePubChat', type: 'boolean', required: true}, + {name: 'disableNotes', type: 'boolean', required: true}, + {name: 'hideUserList', type: 'boolean', required: true}, + {name: 'lockOnJoin', type: 'boolean', required: true}, + {name: 'lockOnJoinConfigurable', type: 'boolean', required: true}, + {name: 'hideViewersCursor', type: 'boolean', required: true}, + {name: 'hideViewersAnnotation', type: 'boolean', required: true}, + ] + ) + const eventName = 'ChangeLockSettingsInMeetingCmdMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/meetingRecordingSetStatus.ts b/bbb-graphql-actions/src/actions/meetingRecordingSetStatus.ts index 10af9e82f7..62a12d6a5b 100644 --- a/bbb-graphql-actions/src/actions/meetingRecordingSetStatus.ts +++ b/bbb-graphql-actions/src/actions/meetingRecordingSetStatus.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'recording', type: 'boolean', required: true}, + ] + ) + const eventName = 'SetRecordingStatusCmdMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/meetingSetMuted.ts b/bbb-graphql-actions/src/actions/meetingSetMuted.ts index 67451e3bb6..0c21b89cbb 100644 --- a/bbb-graphql-actions/src/actions/meetingSetMuted.ts +++ b/bbb-graphql-actions/src/actions/meetingSetMuted.ts @@ -1,8 +1,15 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'muted', type: 'boolean', required: true}, + {name: 'exceptPresenter', type: 'boolean', required: false}, + ] + ) + const eventName = (input.exceptPresenter || false) ? 'MuteAllExceptPresentersCmdMsg' : diff --git a/bbb-graphql-actions/src/actions/meetingSetWebcamOnlyForModerator.ts b/bbb-graphql-actions/src/actions/meetingSetWebcamOnlyForModerator.ts index c0f99ba0e5..fa59c50c1d 100644 --- a/bbb-graphql-actions/src/actions/meetingSetWebcamOnlyForModerator.ts +++ b/bbb-graphql-actions/src/actions/meetingSetWebcamOnlyForModerator.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'webcamsOnlyForModerator', type: 'boolean', required: true}, + ] + ) + const eventName = 'UpdateWebcamsOnlyForModeratorCmdMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/pluginDataChannelDeleteEntry.ts b/bbb-graphql-actions/src/actions/pluginDataChannelDeleteEntry.ts index 1b7c23b037..5aae2a066e 100644 --- a/bbb-graphql-actions/src/actions/pluginDataChannelDeleteEntry.ts +++ b/bbb-graphql-actions/src/actions/pluginDataChannelDeleteEntry.ts @@ -1,7 +1,17 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { - const eventName = `PluginDataChannelDeleteMessageMsg`; + throwErrorIfInvalidInput(input, + [ + {name: 'pluginName', type: 'string', required: true}, + {name: 'channelName', type: 'string', required: true}, + {name: 'subChannelName', type: 'string', required: true}, + {name: 'entryId', type: 'string', required: true}, + ] + ) + + const eventName = `PluginDataChannelDeleteEntryMsg`; const routing = { meetingId: sessionVariables['x-hasura-meetingid'] as String, diff --git a/bbb-graphql-actions/src/actions/pluginDataChannelPushEntry.ts b/bbb-graphql-actions/src/actions/pluginDataChannelPushEntry.ts index 9d90c2054e..e27724fabc 100644 --- a/bbb-graphql-actions/src/actions/pluginDataChannelPushEntry.ts +++ b/bbb-graphql-actions/src/actions/pluginDataChannelPushEntry.ts @@ -1,7 +1,19 @@ import { RedisMessage } from '../types'; import { ValidationError } from '../types/ValidationError'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'pluginName', type: 'string', required: true}, + {name: 'subChannelName', type: 'string', required: true}, + {name: 'channelName', type: 'string', required: true}, + {name: 'payloadJson', type: 'json', required: true}, + {name: 'toRoles', type: 'stringArray', required: true}, + {name: 'toUserIds', type: 'stringArray', required: true}, + ] + ) + const eventName = `PluginDataChannelPushEntryMsg`; const routing = { @@ -15,12 +27,6 @@ export default function buildRedisMessage(sessionVariables: Recordinput.payloadJson); - } catch (e) { - throw new ValidationError('Field `payloadJson` contains an invalid Json.', 400); - } - const body = { pluginName: input.pluginName, channelName: input.channelName, diff --git a/bbb-graphql-actions/src/actions/pluginDataChannelReplaceEntry.ts b/bbb-graphql-actions/src/actions/pluginDataChannelReplaceEntry.ts new file mode 100644 index 0000000000..ed22c24020 --- /dev/null +++ b/bbb-graphql-actions/src/actions/pluginDataChannelReplaceEntry.ts @@ -0,0 +1,38 @@ +import { RedisMessage } from '../types'; +import { ValidationError } from '../types/ValidationError'; +import {throwErrorIfInvalidInput} from "../imports/validation"; + +export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'pluginName', type: 'string', required: true}, + {name: 'subChannelName', type: 'string', required: true}, + {name: 'channelName', type: 'string', required: true}, + {name: 'payloadJson', type: 'json', required: true}, + {name: 'entryId', type: 'string', required: true}, + ] + ) + + const eventName = `PluginDataChannelReplaceEntryMsg`; + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as String, + userId: sessionVariables['x-hasura-userid'] as String + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId + }; + + const body = { + pluginName: input.pluginName, + channelName: input.channelName, + subChannelName: input.subChannelName, + payloadJson: input.payloadJson, + entryId: input.entryId, + }; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/pluginDataChannelReset.ts b/bbb-graphql-actions/src/actions/pluginDataChannelReset.ts index 0a92b27ac4..24fa9ea24b 100644 --- a/bbb-graphql-actions/src/actions/pluginDataChannelReset.ts +++ b/bbb-graphql-actions/src/actions/pluginDataChannelReset.ts @@ -1,6 +1,15 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'pluginName', type: 'string', required: true}, + {name: 'channelName', type: 'string', required: true}, + {name: 'subChannelName', type: 'string', required: true}, + ] + ) + const eventName = `PluginDataChannelResetMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/pluginLearningAnalyticsDashboardSendGenericData.ts b/bbb-graphql-actions/src/actions/pluginLearningAnalyticsDashboardSendGenericData.ts new file mode 100644 index 0000000000..3b831e747f --- /dev/null +++ b/bbb-graphql-actions/src/actions/pluginLearningAnalyticsDashboardSendGenericData.ts @@ -0,0 +1,45 @@ +import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; + +export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'pluginName', type: 'string', required: true}, + {name: 'genericDataForLearningAnalyticsDashboard', type: 'json', required: true}, + ] + ) + + + const genericDataForLearningAnalyticsDashboard = input[ + 'genericDataForLearningAnalyticsDashboard' + ] as Record; + if(genericDataForLearningAnalyticsDashboard) { + throwErrorIfInvalidInput(genericDataForLearningAnalyticsDashboard, + [ + {name: 'cardTitle', type: 'string', required: true}, + {name: 'columnTitle', type: 'string', required: true}, + {name: 'value', type: 'string', required: true}, + ] + ) + } + + const eventName = `PluginLearningAnalyticsDashboardSendGenericDataMsg`; + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as String, + userId: sessionVariables['x-hasura-userid'] as String + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId + }; + + const body = { + pluginName: input.pluginName, + genericDataForLearningAnalyticsDashboard: input.genericDataForLearningAnalyticsDashboard, + }; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/pollCancel.ts b/bbb-graphql-actions/src/actions/pollCancel.ts index 572053b14c..9ef887e9f3 100644 --- a/bbb-graphql-actions/src/actions/pollCancel.ts +++ b/bbb-graphql-actions/src/actions/pollCancel.ts @@ -3,6 +3,7 @@ import {throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + const eventName = `StopPollReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/pollCreate.ts b/bbb-graphql-actions/src/actions/pollCreate.ts index e38e8bf194..c5bb386449 100644 --- a/bbb-graphql-actions/src/actions/pollCreate.ts +++ b/bbb-graphql-actions/src/actions/pollCreate.ts @@ -1,9 +1,20 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; import {ValidationError} from "../types/ValidationError"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'pollId', type: 'string', required: true}, + {name: 'pollType', type: 'string', required: true}, + {name: 'secretPoll', type: 'boolean', required: true}, + {name: 'question', type: 'string', required: true}, + {name: 'isMultipleResponse', type: 'boolean', required: true}, + {name: 'answers', type: 'stringArray', required: false}, + ] + ) + const eventName = input.pollType === 'CUSTOM' ? `StartCustomPollReqMsg` : `StartPollReqMsg` const routing = { diff --git a/bbb-graphql-actions/src/actions/pollPublishResult.ts b/bbb-graphql-actions/src/actions/pollPublishResult.ts index ddeea372e0..7c8279726c 100644 --- a/bbb-graphql-actions/src/actions/pollPublishResult.ts +++ b/bbb-graphql-actions/src/actions/pollPublishResult.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'pollId', type: 'string', required: true}, + ] + ) + const eventName = `ShowPollResultReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/pollSubmitUserTypedVote.ts b/bbb-graphql-actions/src/actions/pollSubmitUserTypedVote.ts index c5cc16f481..2cb568091f 100644 --- a/bbb-graphql-actions/src/actions/pollSubmitUserTypedVote.ts +++ b/bbb-graphql-actions/src/actions/pollSubmitUserTypedVote.ts @@ -1,6 +1,14 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'pollId', type: 'string', required: true}, + {name: 'answer', type: 'string', required: true}, + ] + ) + const eventName = `RespondToTypedPollReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/pollSubmitUserVote.ts b/bbb-graphql-actions/src/actions/pollSubmitUserVote.ts index 457484c381..57a5acd362 100644 --- a/bbb-graphql-actions/src/actions/pollSubmitUserVote.ts +++ b/bbb-graphql-actions/src/actions/pollSubmitUserVote.ts @@ -1,6 +1,14 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'pollId', type: 'string', required: true}, + {name: 'answerIds', type: 'intArray', required: true}, + ] + ) + const eventName = `RespondToPollReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presAnnotationDelete.ts b/bbb-graphql-actions/src/actions/presAnnotationDelete.ts index 69a1f13ba9..d8703dae7f 100644 --- a/bbb-graphql-actions/src/actions/presAnnotationDelete.ts +++ b/bbb-graphql-actions/src/actions/presAnnotationDelete.ts @@ -1,6 +1,14 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'pageId', type: 'string', required: true}, + {name: 'annotationsIds', type: 'stringArray', required: true}, + ] + ) + const eventName = `DeleteWhiteboardAnnotationsPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presAnnotationDeleteAll.ts b/bbb-graphql-actions/src/actions/presAnnotationDeleteAll.ts index 6d26a6b160..3c3bd2dd91 100644 --- a/bbb-graphql-actions/src/actions/presAnnotationDeleteAll.ts +++ b/bbb-graphql-actions/src/actions/presAnnotationDeleteAll.ts @@ -1,7 +1,14 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { - const eventName = `DeleteWhiteboardAnnotationsPubMsg`; + throwErrorIfInvalidInput(input, + [ + {name: 'pageId', type: 'string', required: true}, + ] + ) + + const eventName = `DeleteWhiteboardAnnotationsPubMsg`; const routing = { meetingId: sessionVariables['x-hasura-meetingid'] as String, diff --git a/bbb-graphql-actions/src/actions/presAnnotationSubmit.ts b/bbb-graphql-actions/src/actions/presAnnotationSubmit.ts index e66893e3af..297bca4982 100644 --- a/bbb-graphql-actions/src/actions/presAnnotationSubmit.ts +++ b/bbb-graphql-actions/src/actions/presAnnotationSubmit.ts @@ -1,7 +1,15 @@ import { RedisMessage } from '../types'; import { ValidationError } from '../types/ValidationError'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'pageId', type: 'string', required: true}, + {name: 'annotations', type: 'jsonArray', required: true}, + ] + ) + const eventName = `SendWhiteboardAnnotationsPubMsg`; const routing = { @@ -15,10 +23,6 @@ export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'presentationId', type: 'string', required: true}, + {name: 'fileStateType', type: 'string', required: true}, + ] + ) + const eventName = `MakePresentationDownloadReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presentationPublishCursor.ts b/bbb-graphql-actions/src/actions/presentationPublishCursor.ts index 2393fbfec5..e8a07cf522 100644 --- a/bbb-graphql-actions/src/actions/presentationPublishCursor.ts +++ b/bbb-graphql-actions/src/actions/presentationPublishCursor.ts @@ -1,6 +1,15 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'whiteboardId', type: 'string', required: true}, + {name: 'xPercent', type: 'number', required: true}, + {name: 'yPercent', type: 'number', required: true}, + ] + ) + const eventName = `SendCursorPositionPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presentationRemove.ts b/bbb-graphql-actions/src/actions/presentationRemove.ts index a484539a7c..a6be86e722 100644 --- a/bbb-graphql-actions/src/actions/presentationRemove.ts +++ b/bbb-graphql-actions/src/actions/presentationRemove.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; import { ValidationError } from '../types/ValidationError'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'presentationId', type: 'string', required: true}, + ] + ) + throwErrorIfNotPresenter(sessionVariables); const eventName = `RemovePresentationPubMsg`; diff --git a/bbb-graphql-actions/src/actions/presentationRequestUploadToken.ts b/bbb-graphql-actions/src/actions/presentationRequestUploadToken.ts index 0efdb2f47d..0eaaeb8756 100644 --- a/bbb-graphql-actions/src/actions/presentationRequestUploadToken.ts +++ b/bbb-graphql-actions/src/actions/presentationRequestUploadToken.ts @@ -1,9 +1,16 @@ import { RedisMessage } from '../types'; -import { ValidationError } from '../types/ValidationError'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'podId', type: 'string', required: true}, + {name: 'filename', type: 'string', required: true}, + {name: 'uploadTemporaryId', type: 'string', required: true}, + ] + ) + const eventName = `PresentationUploadTokenReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presentationSetCurrent.ts b/bbb-graphql-actions/src/actions/presentationSetCurrent.ts index 4537e18793..3badb3f212 100644 --- a/bbb-graphql-actions/src/actions/presentationSetCurrent.ts +++ b/bbb-graphql-actions/src/actions/presentationSetCurrent.ts @@ -1,9 +1,15 @@ import { RedisMessage } from '../types'; import { ValidationError } from '../types/ValidationError'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'presentationId', type: 'string', required: true}, + ] + ) + const eventName = `SetCurrentPresentationPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presentationSetDownloadable.ts b/bbb-graphql-actions/src/actions/presentationSetDownloadable.ts index 33ee462298..17723c0079 100644 --- a/bbb-graphql-actions/src/actions/presentationSetDownloadable.ts +++ b/bbb-graphql-actions/src/actions/presentationSetDownloadable.ts @@ -1,8 +1,16 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'presentationId', type: 'string', required: true}, + {name: 'downloadable', type: 'boolean', required: true}, + {name: 'fileStateType', type: 'string', required: true}, + ] + ) + const eventName = `SetPresentationDownloadablePubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presentationSetPage.ts b/bbb-graphql-actions/src/actions/presentationSetPage.ts index dcdd7d3f0e..915aa461d5 100644 --- a/bbb-graphql-actions/src/actions/presentationSetPage.ts +++ b/bbb-graphql-actions/src/actions/presentationSetPage.ts @@ -1,9 +1,16 @@ import { RedisMessage } from '../types'; import { ValidationError } from '../types/ValidationError'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'presentationId', type: 'string', required: true}, + {name: 'pageId', type: 'string', required: true}, + ] + ) + const eventName = `SetCurrentPagePubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presentationSetPageInfiniteWhiteboard.ts b/bbb-graphql-actions/src/actions/presentationSetPageInfiniteWhiteboard.ts new file mode 100644 index 0000000000..80390526ec --- /dev/null +++ b/bbb-graphql-actions/src/actions/presentationSetPageInfiniteWhiteboard.ts @@ -0,0 +1,32 @@ +import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; + +export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'infiniteWhiteboard', type: 'boolean', required: true}, + {name: 'pageId', type: 'string', required: true}, + ] + ) + + const eventName = `SetPageInfiniteWhiteboardPubMsg`; + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as string, + userId: sessionVariables['x-hasura-userid'] as string + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId + }; + + const body = { + pageId: input.pageId, + infiniteWhiteboard: input.infiniteWhiteboard, + }; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/presentationSetRenderedInToast.ts b/bbb-graphql-actions/src/actions/presentationSetRenderedInToast.ts index d35b9301aa..cee04a7c7b 100644 --- a/bbb-graphql-actions/src/actions/presentationSetRenderedInToast.ts +++ b/bbb-graphql-actions/src/actions/presentationSetRenderedInToast.ts @@ -1,9 +1,14 @@ import { RedisMessage } from '../types'; -import { ValidationError } from '../types/ValidationError'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'presentationId', type: 'string', required: true}, + ] + ) + const eventName = `SetPresentationRenderedInToastPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presentationSetWriters.ts b/bbb-graphql-actions/src/actions/presentationSetWriters.ts index 9c62e05501..94b63a0121 100644 --- a/bbb-graphql-actions/src/actions/presentationSetWriters.ts +++ b/bbb-graphql-actions/src/actions/presentationSetWriters.ts @@ -1,9 +1,16 @@ import { RedisMessage } from '../types'; import { ValidationError } from '../types/ValidationError'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'pageId', type: 'string', required: true}, + {name: 'usersIds', type: 'stringArray', required: true}, + ] + ) + const eventName = `ModifyWhiteboardAccessPubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/presentationSetZoom.ts b/bbb-graphql-actions/src/actions/presentationSetZoom.ts index dbc0f565e6..e1c1e6e64b 100644 --- a/bbb-graphql-actions/src/actions/presentationSetZoom.ts +++ b/bbb-graphql-actions/src/actions/presentationSetZoom.ts @@ -1,9 +1,20 @@ import { RedisMessage } from '../types'; -import { ValidationError } from '../types/ValidationError'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'presentationId', type: 'string', required: true}, + {name: 'pageId', type: 'string', required: true}, + {name: 'pageNum', type: 'int', required: true}, + {name: 'xOffset', type: 'number', required: true}, + {name: 'yOffset', type: 'number', required: true}, + {name: 'widthRatio', type: 'number', required: true}, + {name: 'heightRatio', type: 'number', required: true}, + ] + ) + const eventName = `ResizeAndMovePagePubMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/sharedNotesCreateSession.ts b/bbb-graphql-actions/src/actions/sharedNotesCreateSession.ts index 2f0cdac7ce..823c6e4921 100644 --- a/bbb-graphql-actions/src/actions/sharedNotesCreateSession.ts +++ b/bbb-graphql-actions/src/actions/sharedNotesCreateSession.ts @@ -1,6 +1,13 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'sharedNotesExtId', type: 'string', required: true}, + ] + ) + const eventName = `PadCreateSessionReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/sharedNotesSetPinned.ts b/bbb-graphql-actions/src/actions/sharedNotesSetPinned.ts index 35fa3f92b2..6336b5a59f 100644 --- a/bbb-graphql-actions/src/actions/sharedNotesSetPinned.ts +++ b/bbb-graphql-actions/src/actions/sharedNotesSetPinned.ts @@ -1,8 +1,15 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotPresenter} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotPresenter} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotPresenter(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'sharedNotesExtId', type: 'string', required: true}, + {name: 'pinned', type: 'boolean', required: true}, + ] + ) + const eventName = `PadPinnedReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/timerActivate.ts b/bbb-graphql-actions/src/actions/timerActivate.ts index 8a64794a4c..3edd0bd236 100644 --- a/bbb-graphql-actions/src/actions/timerActivate.ts +++ b/bbb-graphql-actions/src/actions/timerActivate.ts @@ -1,8 +1,17 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'stopwatch', type: 'boolean', required: true}, + {name: 'running', type: 'boolean', required: true}, + {name: 'time', type: 'int', required: true}, + {name: 'track', type: 'string', required: false}, + ] + ) + const eventName = `ActivateTimerReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/timerDeactivate.ts b/bbb-graphql-actions/src/actions/timerDeactivate.ts index 038a29050c..6c7a8a766a 100644 --- a/bbb-graphql-actions/src/actions/timerDeactivate.ts +++ b/bbb-graphql-actions/src/actions/timerDeactivate.ts @@ -3,6 +3,7 @@ import {throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + const eventName = `DeactivateTimerReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/timerReset.ts b/bbb-graphql-actions/src/actions/timerReset.ts index 3f4fae28e3..1910e3f2a3 100644 --- a/bbb-graphql-actions/src/actions/timerReset.ts +++ b/bbb-graphql-actions/src/actions/timerReset.ts @@ -3,6 +3,7 @@ import {throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + const eventName = `ResetTimerReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/timerSetSongTrack.ts b/bbb-graphql-actions/src/actions/timerSetSongTrack.ts index 3e486e2130..74e08478f3 100644 --- a/bbb-graphql-actions/src/actions/timerSetSongTrack.ts +++ b/bbb-graphql-actions/src/actions/timerSetSongTrack.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'track', type: 'string', required: true}, + ] + ) + const eventName = `SetTrackReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/timerSetTime.ts b/bbb-graphql-actions/src/actions/timerSetTime.ts index 2cb9cd2984..26ce5336af 100644 --- a/bbb-graphql-actions/src/actions/timerSetTime.ts +++ b/bbb-graphql-actions/src/actions/timerSetTime.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'time', type: 'int', required: true}, + ] + ) + const eventName = `SetTimerReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/timerStart.ts b/bbb-graphql-actions/src/actions/timerStart.ts index 07644d4425..b57751fec9 100644 --- a/bbb-graphql-actions/src/actions/timerStart.ts +++ b/bbb-graphql-actions/src/actions/timerStart.ts @@ -3,6 +3,7 @@ import {throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + const eventName = `StartTimerReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/timerStop.ts b/bbb-graphql-actions/src/actions/timerStop.ts index e38b1a6177..fe102e2140 100644 --- a/bbb-graphql-actions/src/actions/timerStop.ts +++ b/bbb-graphql-actions/src/actions/timerStop.ts @@ -3,6 +3,7 @@ import {throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + const eventName = `StopTimerReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/timerSwitchMode.ts b/bbb-graphql-actions/src/actions/timerSwitchMode.ts index e484a28c77..839c0803c4 100644 --- a/bbb-graphql-actions/src/actions/timerSwitchMode.ts +++ b/bbb-graphql-actions/src/actions/timerSwitchMode.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'stopwatch', type: 'boolean', required: true}, + ] + ) + const eventName = `SwitchTimerReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userEjectCameras.ts b/bbb-graphql-actions/src/actions/userEjectCameras.ts index 0fac5a1bf6..5a9374b05f 100644 --- a/bbb-graphql-actions/src/actions/userEjectCameras.ts +++ b/bbb-graphql-actions/src/actions/userEjectCameras.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: true}, + ] + ) + const eventName = 'EjectUserCamerasCmdMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/userEjectFromMeeting.ts b/bbb-graphql-actions/src/actions/userEjectFromMeeting.ts index 4c3f4fa2c0..8838e61cf9 100644 --- a/bbb-graphql-actions/src/actions/userEjectFromMeeting.ts +++ b/bbb-graphql-actions/src/actions/userEjectFromMeeting.ts @@ -1,8 +1,15 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: true}, + {name: 'banUser', type: 'boolean', required: true}, + ] + ) + const eventName = `EjectUserFromMeetingCmdMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userEjectFromVoice.ts b/bbb-graphql-actions/src/actions/userEjectFromVoice.ts index 39d47a61c0..3d38d028c4 100644 --- a/bbb-graphql-actions/src/actions/userEjectFromVoice.ts +++ b/bbb-graphql-actions/src/actions/userEjectFromVoice.ts @@ -1,8 +1,15 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: true}, + {name: 'banUser', type: 'boolean', required: false}, + ] + ) + const eventName = 'EjectUserFromVoiceCmdMsg'; const routing = { diff --git a/bbb-graphql-actions/src/actions/userJoinMeeting.ts b/bbb-graphql-actions/src/actions/userJoinMeeting.ts index 1898af69d9..25d961a62d 100644 --- a/bbb-graphql-actions/src/actions/userJoinMeeting.ts +++ b/bbb-graphql-actions/src/actions/userJoinMeeting.ts @@ -1,6 +1,15 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'authToken', type: 'string', required: true}, + {name: 'clientType', type: 'string', required: true}, + {name: 'clientIsMobile', type: 'boolean', required: true}, + ] + ) + const eventName = `UserJoinMeetingReqMsg`; const routing = { @@ -18,6 +27,7 @@ export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'away', type: 'boolean', required: true}, + ] + ) + const eventName = `ChangeUserAwayReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userSetCameraPinned.ts b/bbb-graphql-actions/src/actions/userSetCameraPinned.ts index 0556b621ea..c94032460a 100644 --- a/bbb-graphql-actions/src/actions/userSetCameraPinned.ts +++ b/bbb-graphql-actions/src/actions/userSetCameraPinned.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: true}, + {name: 'pinned', type: 'boolean', required: true}, + ] + ) const eventName = `ChangeUserPinStateReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/captionSetOwner.ts b/bbb-graphql-actions/src/actions/userSetCaptionLocale.ts similarity index 63% rename from bbb-graphql-actions/src/actions/captionSetOwner.ts rename to bbb-graphql-actions/src/actions/userSetCaptionLocale.ts index 98ca32a4cf..38a97025dd 100644 --- a/bbb-graphql-actions/src/actions/captionSetOwner.ts +++ b/bbb-graphql-actions/src/actions/userSetCaptionLocale.ts @@ -1,7 +1,15 @@ +import { throwErrorIfInvalidInput } from '../imports/validation'; import { RedisMessage } from '../types'; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { - const eventName = `UpdateCaptionOwnerPubMsg`; + const eventName = `SetUserCaptionLocaleReqMsg`; + + throwErrorIfInvalidInput(input, + [ + {name: 'locale', type: 'string', required: true}, + {name: 'provider', type: 'string', required: true}, + ] + ) const routing = { meetingId: sessionVariables['x-hasura-meetingid'] as String, @@ -15,9 +23,8 @@ export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'userClientSettingsJson', type: 'json', required: true}, + ] + ) + + const eventName = `SetUserClientSettingsReqMsg`; + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as String, + userId: sessionVariables['x-hasura-userid'] as String + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId + }; + + const body = { + userClientSettingsJson: input.userClientSettingsJson, + }; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/userSetConnectionAlive.ts b/bbb-graphql-actions/src/actions/userSetConnectionAlive.ts index 226971db65..96d0991f63 100644 --- a/bbb-graphql-actions/src/actions/userSetConnectionAlive.ts +++ b/bbb-graphql-actions/src/actions/userSetConnectionAlive.ts @@ -1,6 +1,13 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'networkRttInMs', type: 'number', required: true}, + ] + ) + const eventName = `UserConnectionAliveReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userSetEchoTestRunning.ts b/bbb-graphql-actions/src/actions/userSetEchoTestRunning.ts new file mode 100644 index 0000000000..2c643859a5 --- /dev/null +++ b/bbb-graphql-actions/src/actions/userSetEchoTestRunning.ts @@ -0,0 +1,21 @@ +import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; + +export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + const eventName = `SetUserEchoTestRunningReqMsg`; + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as String, + userId: sessionVariables['x-hasura-userid'] as String + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId + }; + + const body = {}; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/userSetEmojiStatus.ts b/bbb-graphql-actions/src/actions/userSetEmojiStatus.ts deleted file mode 100644 index 8a5f4ca869..0000000000 --- a/bbb-graphql-actions/src/actions/userSetEmojiStatus.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { RedisMessage } from '../types'; - -export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { - const eventName = `ChangeUserEmojiCmdMsg`; - - const routing = { - meetingId: sessionVariables['x-hasura-meetingid'] as String, - userId: sessionVariables['x-hasura-userid'] as String - }; - - const header = { - name: eventName, - meetingId: routing.meetingId, - userId: routing.userId - }; - - const body = { - userId: routing.userId, - emoji: input.emoji - }; - - return { eventName, routing, header, body }; -} diff --git a/bbb-graphql-actions/src/actions/userSetExitReason.ts b/bbb-graphql-actions/src/actions/userSetExitReason.ts index 08ec948417..d85e5ba83d 100644 --- a/bbb-graphql-actions/src/actions/userSetExitReason.ts +++ b/bbb-graphql-actions/src/actions/userSetExitReason.ts @@ -1,6 +1,13 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'exitReason', type: 'string', required: true}, + ] + ) + const eventName = `ChangeUserExitReasonCmdMsg`; //TODO Akka does not expect to receive this message diff --git a/bbb-graphql-actions/src/actions/userSetLocked.ts b/bbb-graphql-actions/src/actions/userSetLocked.ts index 45cee9e966..656ed44322 100644 --- a/bbb-graphql-actions/src/actions/userSetLocked.ts +++ b/bbb-graphql-actions/src/actions/userSetLocked.ts @@ -1,8 +1,15 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: true}, + {name: 'locked', type: 'boolean', required: true}, + ] + ) + const eventName = `LockUserInMeetingCmdMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userSetMobileFlag.ts b/bbb-graphql-actions/src/actions/userSetMobileFlag.ts deleted file mode 100644 index 389adcd67c..0000000000 --- a/bbb-graphql-actions/src/actions/userSetMobileFlag.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { RedisMessage } from '../types'; - -export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { - const eventName = `ChangeUserMobileFlagReqMsg`; - - const routing = { - meetingId: sessionVariables['x-hasura-meetingid'] as String, - userId: sessionVariables['x-hasura-userid'] as String - }; - - const header = { - name: eventName, - meetingId: routing.meetingId, - userId: routing.userId - }; - - const body = { - userId: routing.userId, - mobile: input.mobile - }; - - return { eventName, routing, header, body }; -} diff --git a/bbb-graphql-actions/src/actions/userSetMuted.ts b/bbb-graphql-actions/src/actions/userSetMuted.ts index 6b6d87b8c5..4e0b276d50 100644 --- a/bbb-graphql-actions/src/actions/userSetMuted.ts +++ b/bbb-graphql-actions/src/actions/userSetMuted.ts @@ -1,7 +1,14 @@ import { RedisMessage } from '../types'; -import {isModerator} from "../imports/validation"; +import {isModerator, throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: false}, + {name: 'muted', type: 'boolean', required: true}, + ] + ) + const eventName = `MuteUserCmdMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userSetPresenter.ts b/bbb-graphql-actions/src/actions/userSetPresenter.ts index 01dcdec05f..f776fed02f 100644 --- a/bbb-graphql-actions/src/actions/userSetPresenter.ts +++ b/bbb-graphql-actions/src/actions/userSetPresenter.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: true}, + ] + ) + const eventName = `AssignPresenterReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userSetRaiseHand.ts b/bbb-graphql-actions/src/actions/userSetRaiseHand.ts index a6bd0b1401..094d7c2dc3 100644 --- a/bbb-graphql-actions/src/actions/userSetRaiseHand.ts +++ b/bbb-graphql-actions/src/actions/userSetRaiseHand.ts @@ -1,7 +1,14 @@ import { RedisMessage } from '../types'; -import {isModerator, throwErrorIfNotModerator} from "../imports/validation"; +import {isModerator, throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: false}, + {name: 'raiseHand', type: 'boolean', required: true}, + ] + ) + const eventName = `ChangeUserRaiseHandReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userSetReactionEmoji.ts b/bbb-graphql-actions/src/actions/userSetReactionEmoji.ts index c1c579f873..4bbed6cb9a 100644 --- a/bbb-graphql-actions/src/actions/userSetReactionEmoji.ts +++ b/bbb-graphql-actions/src/actions/userSetReactionEmoji.ts @@ -1,6 +1,13 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'reactionEmoji', type: 'string', required: true}, + ] + ) + const eventName = `ChangeUserReactionEmojiReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userSetRole.ts b/bbb-graphql-actions/src/actions/userSetRole.ts index 0d10f47a4f..d153474b06 100644 --- a/bbb-graphql-actions/src/actions/userSetRole.ts +++ b/bbb-graphql-actions/src/actions/userSetRole.ts @@ -1,8 +1,15 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'userId', type: 'string', required: true}, + {name: 'role', type: 'string', required: true}, + ] + ) + const eventName = `ChangeUserRoleCmdMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userSetSpeechLocale.ts b/bbb-graphql-actions/src/actions/userSetSpeechLocale.ts index e7d981c0cc..d9dc524d15 100644 --- a/bbb-graphql-actions/src/actions/userSetSpeechLocale.ts +++ b/bbb-graphql-actions/src/actions/userSetSpeechLocale.ts @@ -1,6 +1,14 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'locale', type: 'string', required: true}, + {name: 'provider', type: 'string', required: true}, + ] + ) + const eventName = `SetUserSpeechLocaleReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userSetSpeechOptions.ts b/bbb-graphql-actions/src/actions/userSetSpeechOptions.ts new file mode 100644 index 0000000000..08d28151b3 --- /dev/null +++ b/bbb-graphql-actions/src/actions/userSetSpeechOptions.ts @@ -0,0 +1,26 @@ +import { RedisMessage } from '../types'; + +export default function buildRedisMessage( + sessionVariables: Record, + input: Record +): RedisMessage { + const eventName = `SetUserSpeechOptionsReqMsg`; + + const routing = { + meetingId: sessionVariables['x-hasura-meetingid'] as String, + userId: sessionVariables['x-hasura-userid'] as String, + }; + + const header = { + name: eventName, + meetingId: routing.meetingId, + userId: routing.userId, + }; + + const body = { + partialUtterances: input.partialUtterances, + minUtteranceLength: input.minUtteranceLength, + }; + + return { eventName, routing, header, body }; +} diff --git a/bbb-graphql-actions/src/actions/userThirdPartyInfoResquest.ts b/bbb-graphql-actions/src/actions/userThirdPartyInfoResquest.ts index ca613e994b..5c3d11a346 100644 --- a/bbb-graphql-actions/src/actions/userThirdPartyInfoResquest.ts +++ b/bbb-graphql-actions/src/actions/userThirdPartyInfoResquest.ts @@ -1,8 +1,14 @@ import { RedisMessage } from '../types'; -import {throwErrorIfNotModerator} from "../imports/validation"; +import {throwErrorIfInvalidInput, throwErrorIfNotModerator} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { throwErrorIfNotModerator(sessionVariables); + throwErrorIfInvalidInput(input, + [ + {name: 'externalUserId', type: 'string', required: true}, + ] + ) + const eventName = `LookUpUserReqMsg`; const routing = { diff --git a/bbb-graphql-actions/src/actions/userTransferVoiceToMeeting.ts b/bbb-graphql-actions/src/actions/userTransferVoiceToMeeting.ts index fc3108e619..055bb6694d 100644 --- a/bbb-graphql-actions/src/actions/userTransferVoiceToMeeting.ts +++ b/bbb-graphql-actions/src/actions/userTransferVoiceToMeeting.ts @@ -1,6 +1,14 @@ import { RedisMessage } from '../types'; +import {throwErrorIfInvalidInput} from "../imports/validation"; export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage { + throwErrorIfInvalidInput(input, + [ + {name: 'fromMeetingId', type: 'string', required: true}, + {name: 'toMeetingId', type: 'string', required: true}, + ] + ) + const eventName = 'TransferUserToMeetingRequestMsg'; const routing = { diff --git a/bbb-graphql-actions/src/imports/validation.ts b/bbb-graphql-actions/src/imports/validation.ts index 9d2e21c8c7..9b05f9a1f1 100644 --- a/bbb-graphql-actions/src/imports/validation.ts +++ b/bbb-graphql-actions/src/imports/validation.ts @@ -2,16 +2,122 @@ import {ValidationError} from "../types/ValidationError"; export const throwErrorIfNotModerator = (sessionVariables: Record) => { if(sessionVariables['x-hasura-moderatorinmeeting'] == "") { - throw new ValidationError('Permission Denied.', 403); + throw new ValidationError('Permission Denied (not moderator).', 403); } }; export const throwErrorIfNotPresenter = (sessionVariables: Record) => { if(sessionVariables['x-hasura-presenterinmeeting'] == "") { - throw new ValidationError('Permission Denied.', 403); + throw new ValidationError('Permission Denied (not presenter).', 403); } }; export const isModerator = (sessionVariables: Record) => { return (sessionVariables['x-hasura-moderatorinmeeting'] !== ""); -}; \ No newline at end of file +}; + + +export type InputParam = { + name: string; + type: 'string' | 'number' | 'int' | 'boolean' | 'json' | 'jsonArray' | 'stringArray' | 'numberArray' | 'intArray' | 'objectArray'; + required: boolean; +}; + +export const throwErrorIfInvalidInput = (input: Record, expectedParams: InputParam[]) => { + for (const param of expectedParams) { + if (param.required && !(param.name in input)) { + throw new ValidationError(`Missing required parameter: '${param.name}'`, 403); + } + + if (param.name in input) { + const value = input[param.name]; + + if (!param.required && value == null) { + //Param is null and it is not required + continue; + } + + switch (param.type) { + case 'string': + if (typeof value !== 'string') { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + break; + case 'number': + if (typeof value !== 'number') { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + break; + case 'int': + if (typeof value !== 'number' || !Number.isInteger(value)) { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + break; + case 'boolean': + if (typeof value !== 'boolean') { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + break; + case 'json': + if (typeof value !== 'object') { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + try { + const jsonString = JSON.stringify(value); + JSON.parse(jsonString); + } catch (e) { + throw new ValidationError(`Parameter '${param.name}' contains an invalid Json.`, 400); + } + break; + case 'jsonArray': + if (typeof value !== 'object' || !Array.isArray(value)) { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + break; + case 'stringArray': + if (typeof value !== 'object' || !Array.isArray(value)) { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + if(value.length > 0) { + if (typeof value[0] !== 'string') { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + } + break; + case 'numberArray': + if (typeof value !== 'object' || !Array.isArray(value)) { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + if(value.length > 0) { + if (typeof value[0] !== 'number') { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + } + break; + case 'intArray': + if (typeof value !== 'object' || !Array.isArray(value)) { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + if(value.length > 0) { + if (typeof value[0] !== 'number' || !Number.isInteger(value[0])) { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + } + break; + case 'objectArray': + if (typeof value !== 'object' || !Array.isArray(value)) { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + if(value.length > 0) { + if (typeof value[0] !== 'object') { + throw new ValidationError(`Parameter '${param.name}' should be of type ${param.type}`, 400); + } + } + break; + default: + throw new ValidationError(`Unknown type for parameter '${param.name}'`, 400); + } + } + } + return true; +} \ No newline at end of file diff --git a/bbb-graphql-actions/src/index.ts b/bbb-graphql-actions/src/index.ts index 65b8ffd404..65733112b8 100644 --- a/bbb-graphql-actions/src/index.ts +++ b/bbb-graphql-actions/src/index.ts @@ -64,11 +64,13 @@ app.post('/', async (req: Request, res: Response) => { res.status(200).json(true); } catch (error) { + const actionName = req.body?.action?.name || 'Unidentified Action'; + if (error instanceof ValidationError) { - res.status(error.status).send({message: error.message}); + res.status(error.status).send({message: `${actionName}: ${error.message}`}); } else { console.error(error); - res.status(400).send({message: 'Internal Server Error'}); + res.status(400).send({message: `${actionName}: Internal Server Error`}); } } }); diff --git a/bbb-graphql-client-test/package-lock.json b/bbb-graphql-client-test/package-lock.json index 330079d05e..75dfae6330 100644 --- a/bbb-graphql-client-test/package-lock.json +++ b/bbb-graphql-client-test/package-lock.json @@ -1,7 +1,7 @@ { "name": "bigbluebutton-graphql", "version": "0.1.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -24,35 +24,51 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", - "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==" + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "license": "MIT" + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@apollo/client": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.7.1.tgz", - "integrity": "sha512-xu5M/l7p9gT9Fx7nF3AQivp0XukjB7TM7tOd5wifIpI8RskYveL4I+rpTijzWrnqCPZabkbzJKH7WEAKdctt9w==", + "version": "3.11.8", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.11.8.tgz", + "integrity": "sha512-CgG1wbtMjsV2pRGe/eYITmV5B8lXUCYljB2gB/6jWTFQcrvirUVvKg7qtFdjYkQSFbIffU1IDyxgeaN81eTjbA==", + "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", - "@wry/context": "^0.7.0", - "@wry/equality": "^0.5.0", - "@wry/trie": "^0.3.0", + "@wry/caches": "^1.0.0", + "@wry/equality": "^0.5.6", + "@wry/trie": "^0.5.0", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.16.1", + "optimism": "^0.18.0", "prop-types": "^15.7.2", + "rehackt": "^0.1.0", "response-iterator": "^0.2.6", "symbol-observable": "^4.0.0", "ts-invariant": "^0.10.3", @@ -60,10 +76,10 @@ "zen-observable-ts": "^1.2.5" }, "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0", + "graphql": "^15.0.0 || ^16.0.0", "graphql-ws": "^5.5.5", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0", "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" }, "peerDependenciesMeta": { @@ -82,11 +98,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" }, "engines": { @@ -94,33 +111,35 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", - "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.5", - "@babel/parser": "^7.20.5", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5", - "convert-source-map": "^1.7.0", + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -134,31 +153,34 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/eslint-parser": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", - "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.1.tgz", + "integrity": "sha512-Y956ghgTT4j7rKesabkh5WeqgSFZVFwaPR0IWFm7KFHFmmJ4afbG49SmfW4S+GyRPx0Dy5jxEWA5t0rpxfElWg==", + "license": "MIT", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": "^10.13.0 || ^12.13.0 || >=14.0.0" }, "peerDependencies": { - "@babel/core": ">=7.11.0", - "eslint": "^7.5.0 || ^8.0.0" + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "license": "Apache-2.0", "engines": { "node": ">=10" } @@ -167,16 +189,18 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", - "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.0", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -185,79 +209,69 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "license": "MIT", "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", - "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.4", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -266,155 +280,131 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", - "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.2.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", + "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "license": "MIT", "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.1", - "@babel/types": "^7.20.2" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -424,110 +414,109 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.20.2" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", - "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", - "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", + "license": "MIT", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -536,10 +525,85 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -547,12 +611,44 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", + "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -562,13 +658,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -577,27 +674,28 @@ "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-proposal-class-properties": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -609,92 +707,15 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.5.tgz", - "integrity": "sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz", + "integrity": "sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==", + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/plugin-syntax-decorators": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-decorators": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -707,6 +728,8 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -722,6 +745,8 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -733,46 +758,15 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -786,6 +780,8 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -798,15 +794,10 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", - "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", "engines": { "node": ">=6.9.0" }, @@ -814,25 +805,11 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -844,6 +821,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -855,6 +833,7 @@ "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -866,6 +845,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -877,11 +857,12 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", - "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.7.tgz", + "integrity": "sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -894,6 +875,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -905,6 +887,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -913,11 +896,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", - "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", + "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -927,11 +911,27 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", + "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -944,6 +944,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -955,6 +956,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -963,11 +965,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -980,6 +983,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -991,6 +995,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1002,6 +1007,7 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1013,6 +1019,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1024,6 +1031,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1035,6 +1043,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1046,6 +1055,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1060,6 +1070,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1071,11 +1082,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1084,28 +1096,64 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", + "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.4" + }, + "engines": { + "node": ">=6.9.0" + }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1115,11 +1163,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1129,11 +1178,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz", - "integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1142,19 +1192,50 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", + "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", + "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.4", "globals": "^11.1.0" }, "engines": { @@ -1165,11 +1246,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1179,11 +1262,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1193,12 +1277,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1208,11 +1293,44 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1222,12 +1340,29 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1237,12 +1372,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", - "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.25.2.tgz", + "integrity": "sha512-InBZ0O8tew5V0K6cHcQ+wgxlrjOw1W4wDXLkOTjLRD8GYhTSkxTVBtdy3MMtvYBrbAWa1Qm3hNoTc1620Yj+Mg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-flow": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-flow": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1252,11 +1388,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1266,13 +1404,30 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1282,11 +1437,28 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", + "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { "node": ">=6.9.0" @@ -1296,11 +1468,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1310,12 +1483,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1325,13 +1499,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1341,14 +1516,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -1358,12 +1534,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1373,12 +1550,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", - "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1388,11 +1566,62 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1402,12 +1631,46 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1417,11 +1680,46 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz", - "integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", + "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -1431,11 +1729,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1445,11 +1744,12 @@ } }, "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.20.2.tgz", - "integrity": "sha512-KS/G8YI8uwMGKErLFOHS/ekhqdHhpEloxs43NecQHVgo2QuQSyJhGIY1fL8UGl9wy5ItVwwoUL4YxVqsplGq2g==", + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.1.tgz", + "integrity": "sha512-SLV/giH/V4SmloZ6Dt40HjTGTAIkxn33TVIHxNGNvo8ezMhrxBkzisj4op1KZYPIOHFLqhv60OHvX+YRu4xbmQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1459,11 +1759,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", + "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1473,15 +1774,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", - "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz", + "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==", + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.19.0" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/types": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -1491,11 +1793,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", + "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", + "license": "MIT", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.18.6" + "@babel/plugin-transform-react-jsx": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1505,12 +1808,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", + "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1520,12 +1824,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", - "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "regenerator-transform": "^0.15.1" + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" }, "engines": { "node": ">=6.9.0" @@ -1535,11 +1840,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1549,16 +1855,17 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", - "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.4.tgz", + "integrity": "sha512-8hsyG+KUYGY0coX6KUCDancA0Vw225KJ2HJO0yCNr1vq5r+lJTleDaJf0K7iOhjw4SWhu03TMBzYTJ9krmzULQ==", + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "semver": "^6.3.0" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1571,16 +1878,18 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1590,12 +1899,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1605,11 +1915,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1619,11 +1930,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1633,11 +1945,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1647,13 +1960,16 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", - "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", + "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.20.2", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-typescript": "^7.20.0" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1663,11 +1979,28 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1677,12 +2010,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1691,38 +2025,46 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", + "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/helper-create-regexp-features-plugin": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz", + "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.4", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1732,45 +2074,62 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.25.4", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.4", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.37.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1783,36 +2142,37 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/preset-react": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", - "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", + "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.18.6", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.24.7", + "@babel/plugin-transform-react-jsx-development": "^7.24.7", + "@babel/plugin-transform-react-pure-annotations": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1822,13 +2182,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1837,55 +2200,49 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", - "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "license": "MIT" }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz", - "integrity": "sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==", + "node_modules/@babel/runtime": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", + "license": "MIT", "dependencies": { - "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1894,12 +2251,13 @@ } }, "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1909,17 +2267,20 @@ "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "license": "MIT" }, "node_modules/@csstools/normalize.css": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", - "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==" + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", + "integrity": "sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ==", + "license": "CC0-1.0" }, "node_modules/@csstools/postcss-cascade-layers": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.2", "postcss-selector-parser": "^6.0.10" @@ -1939,6 +2300,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -1958,6 +2320,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -1976,6 +2339,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -1994,6 +2358,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -2013,6 +2378,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -2032,6 +2398,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2050,6 +2417,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2068,6 +2436,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -2087,6 +2456,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2101,6 +2471,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2119,6 +2490,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2137,6 +2509,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -2155,6 +2528,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", + "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" }, @@ -2167,30 +2541,55 @@ } }, "node_modules/@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "license": "CC0-1.0", "engines": { - "node": "^12 || ^14 || >=16" + "node": "^14 || ^16 || >=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.2", "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -2207,12 +2606,14 @@ "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -2227,6 +2628,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -2238,6 +2640,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -2245,21 +2648,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@graphql-typed-document-node/core": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz", - "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "license": "MIT", "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -2270,6 +2685,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -2279,14 +2695,107 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "license": "BSD-3-Clause" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -2302,62 +2811,16 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "license": "MIT", "engines": { "node": ">=8" } @@ -2366,6 +2829,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "@types/node": "*", @@ -2378,74 +2842,73 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/console/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@jest/console/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@jest/console/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/@jest/console/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@jest/console/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/console/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/console/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@jest/console/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/core": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "license": "MIT", "dependencies": { "@jest/console": "^27.5.1", "@jest/reporters": "^27.5.1", @@ -2488,74 +2951,73 @@ } } }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@jest/core/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@jest/core/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/@jest/core/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@jest/core/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/core/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/core/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@jest/core/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/environment": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "license": "MIT", "dependencies": { "@jest/fake-timers": "^27.5.1", "@jest/types": "^27.5.1", @@ -2566,21 +3028,39 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/expect-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz", - "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==", + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "jest-get-type": "^29.2.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/expect-utils/node_modules/jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "node_modules/@jest/environment/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -2589,6 +3069,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "@sinonjs/fake-timers": "^8.0.1", @@ -2601,10 +3082,73 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, "node_modules/@jest/globals": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", "@jest/types": "^27.5.1", @@ -2614,10 +3158,119 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/@jest/globals/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/globals/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, "node_modules/@jest/reporters": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "^27.5.1", @@ -2657,93 +3310,74 @@ } } }, - "node_modules/@jest/reporters/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@jest/reporters/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@jest/reporters/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/@jest/reporters/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@jest/reporters/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/reporters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/reporters/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/@jest/reporters/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "license": "MIT", "dependencies": { "callsites": "^3.0.0", "graceful-fs": "^4.2.9", @@ -2757,6 +3391,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -2765,6 +3400,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "license": "MIT", "dependencies": { "@jest/console": "^27.5.1", "@jest/types": "^27.5.1", @@ -2775,10 +3411,36 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/@jest/test-result/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-result/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, "node_modules/@jest/test-sequencer": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "license": "MIT", "dependencies": { "@jest/test-result": "^27.5.1", "graceful-fs": "^4.2.9", @@ -2793,6 +3455,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "license": "MIT", "dependencies": { "@babel/core": "^7.1.0", "@jest/types": "^27.5.1", @@ -2814,82 +3477,11 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/transform/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/transform/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/transform/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types": { + "node_modules/@jest/transform/node_modules/@jest/types": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -2901,111 +3493,69 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@jest/transform/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@jest/transform/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { - "node": ">=7.0.0" + "node": ">=0.10.0" } }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -3015,29 +3565,61 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "license": "MIT" }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "license": "MIT", "dependencies": { "eslint-scope": "5.1.1" } @@ -3046,6 +3628,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -3058,6 +3641,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -3066,6 +3650,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -3078,6 +3663,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", "engines": { "node": ">= 8" } @@ -3086,6 +3672,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -3094,19 +3681,28 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", - "integrity": "sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", + "integrity": "sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==", + "license": "MIT", "dependencies": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", + "ansi-html": "^0.0.9", "core-js-pure": "^3.23.3", "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", "html-entities": "^2.1.0", "loader-utils": "^2.0.4", - "schema-utils": "^3.0.0", + "schema-utils": "^4.2.0", "source-map": "^0.7.3" }, "engines": { @@ -3116,9 +3712,9 @@ "@types/webpack": "4.x || 5.x", "react-refresh": ">=0.10.0 <1.0.0", "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <4.0.0", + "type-fest": ">=0.17.0 <5.0.0", "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x", + "webpack-dev-server": "3.x || 4.x || 5.x", "webpack-hot-middleware": "2.x", "webpack-plugin-serve": "0.x || 1.x" }, @@ -3147,6 +3743,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.10.4", "@rollup/pluginutils": "^3.1.0" @@ -3169,6 +3766,7 @@ "version": "11.2.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.1.0", "@types/resolve": "1.17.1", @@ -3188,6 +3786,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.1.0", "magic-string": "^0.25.7" @@ -3200,6 +3799,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "license": "MIT", "dependencies": { "@types/estree": "0.0.39", "estree-walker": "^1.0.1", @@ -3215,22 +3815,32 @@ "node_modules/@rollup/pluginutils/node_modules/@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "license": "MIT" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "license": "MIT" }, "node_modules/@rushstack/eslint-patch": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", - "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", + "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", + "license": "MIT" }, "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } @@ -3239,6 +3849,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^1.7.0" } @@ -3247,6 +3858,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "license": "Apache-2.0", "dependencies": { "ejs": "^3.1.6", "json5": "^2.2.0", @@ -3258,6 +3870,7 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3270,6 +3883,7 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3282,6 +3896,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3294,6 +3909,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3306,6 +3922,7 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3318,6 +3935,7 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3330,6 +3948,7 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3342,6 +3961,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3354,6 +3974,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "license": "MIT", "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", @@ -3376,6 +3997,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "license": "MIT", "dependencies": { "@svgr/plugin-jsx": "^5.5.0", "camelcase": "^6.2.0", @@ -3393,6 +4015,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "license": "MIT", "dependencies": { "@babel/types": "^7.12.6" }, @@ -3408,6 +4031,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "license": "MIT", "dependencies": { "@babel/core": "^7.12.3", "@svgr/babel-preset": "^5.5.0", @@ -3426,6 +4050,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "license": "MIT", "dependencies": { "cosmiconfig": "^7.0.0", "deepmerge": "^4.2.2", @@ -3443,6 +4068,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "license": "MIT", "dependencies": { "@babel/core": "^7.12.3", "@babel/plugin-transform-react-constant-elements": "^7.12.1", @@ -3462,99 +4088,30 @@ } }, "node_modules/@testing-library/dom": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", - "integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", + "lz-string": "^1.5.0", "pretty-format": "^27.0.2" }, "engines": { - "node": ">=12" - } - }, - "node_modules/@testing-library/dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@testing-library/dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": ">=18" } }, "node_modules/@testing-library/jest-dom": { - "version": "5.16.5", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", - "integrity": "sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", + "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.0.1", "@babel/runtime": "^7.9.2", @@ -3572,32 +4129,11 @@ "yarn": ">=1" } }, - "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dependencies": { - "deep-equal": "^2.0.5" - } - }, "node_modules/@testing-library/jest-dom/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3606,45 +4142,11 @@ "node": ">=8" } }, - "node_modules/@testing-library/jest-dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@testing-library/jest-dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/react": { "version": "13.4.0", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", "@testing-library/dom": "^8.5.0", @@ -3658,10 +4160,39 @@ "react-dom": "^18.0.0" } }, + "node_modules/@testing-library/react/node_modules/@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, "node_modules/@testing-library/user-event": { "version": "13.5.0", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5" }, @@ -3677,6 +4208,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "license": "MIT", "engines": { "node": ">= 6" } @@ -3685,134 +4217,141 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "license": "ISC", "engines": { "node": ">=10.13.0" } }, "node_modules/@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==" + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "license": "MIT" }, "node_modules/@types/babel__core": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", - "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", - "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "license": "MIT", "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" } }, "node_modules/@types/eslint": { - "version": "8.4.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", - "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "license": "MIT" }, "node_modules/@types/express": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", - "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.31", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", - "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -3820,234 +4359,77 @@ "node_modules/@types/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "license": "MIT" }, "node_modules/@types/http-proxy": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", - "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/jest": { - "version": "29.2.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.3.tgz", - "integrity": "sha512-6XwoEbmatfyoCjWRX7z0fKMmgYKe9+/HrviJ5k0X/tjJWHGAezZOfYaxqQKuzG/TvQyr+ktjm4jgbk0s4/oF2w==", + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, - "node_modules/@types/jest/node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", - "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/@jest/types": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", - "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", - "dependencies": { - "@jest/schemas": "^29.0.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/@types/yargs": { - "version": "17.0.15", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz", - "integrity": "sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, "node_modules/@types/jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@types/jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@types/jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@types/jest/node_modules/diff-sequences": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", - "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==", - "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" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@types/jest/node_modules/jest-diff": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz", - "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-matcher-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz", - "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-message-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", - "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.3.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", - "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", - "dependencies": { - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/@types/jest/node_modules/pretty-format": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", - "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4055,97 +4437,99 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/jest/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/@types/jest/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - }, - "node_modules/@types/jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "license": "MIT" }, "node_modules/@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" }, "node_modules/@types/node": { - "version": "18.11.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz", - "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==" + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" }, "node_modules/@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "license": "MIT" }, "node_modules/@types/q": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", - "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", + "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==", + "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "license": "MIT" }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" }, "node_modules/@types/react": { - "version": "18.0.25", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.25.tgz", - "integrity": "sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g==", + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", + "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", + "license": "MIT", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { - "version": "18.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", - "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "license": "MIT", "dependencies": { "@types/react": "*" } @@ -4154,6 +4538,7 @@ "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -4161,94 +4546,113 @@ "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "node_modules/@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" }, "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } }, "node_modules/@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "license": "MIT", "dependencies": { "@types/express": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "license": "MIT", "dependencies": { - "@types/mime": "*", - "@types/node": "*" + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" } }, "node_modules/@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "license": "MIT" }, "node_modules/@types/testing-library__jest-dom": { - "version": "5.14.5", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz", - "integrity": "sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==", + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", + "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "license": "MIT", "dependencies": { "@types/jest": "*" } }, "node_modules/@types/trusted-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", - "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz", - "integrity": "sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.45.0", - "@typescript-eslint/type-utils": "5.45.0", - "@typescript-eslint/utils": "5.45.0", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" }, @@ -4270,11 +4674,12 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.45.0.tgz", - "integrity": "sha512-DnRQg5+3uHHt/gaifTjwg9OKbg9/TWehfJzYHQIDJboPEbF897BKDE/qoqMhW7nf0jWRV1mwVXTaUvtB1/9Gwg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "5.45.0" + "@typescript-eslint/utils": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4288,13 +4693,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.0.tgz", - "integrity": "sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "5.45.0", - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/typescript-estree": "5.45.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "engines": { @@ -4314,12 +4720,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz", - "integrity": "sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/visitor-keys": "5.45.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4330,12 +4737,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz", - "integrity": "sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "5.45.0", - "@typescript-eslint/utils": "5.45.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -4356,9 +4764,10 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.0.tgz", - "integrity": "sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4368,12 +4777,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz", - "integrity": "sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/visitor-keys": "5.45.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4394,17 +4804,18 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.45.0.tgz", - "integrity": "sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "license": "MIT", "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.45.0", - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/typescript-estree": "5.45.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "engines": { @@ -4422,6 +4833,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -4434,16 +4846,18 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz", - "integrity": "sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -4454,10 +4868,17 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "license": "ISC" + }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -4466,22 +4887,26 @@ "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -4491,12 +4916,14 @@ "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -4508,6 +4935,7 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -4516,6 +4944,7 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } @@ -4523,12 +4952,14 @@ "node_modules/@webassemblyjs/utf8": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -4544,6 +4975,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -4556,6 +4988,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -4567,6 +5000,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", @@ -4580,15 +5014,29 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, + "node_modules/@wry/caches": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.1.tgz", + "integrity": "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@wry/context": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.0.tgz", - "integrity": "sha512-LcDAiYWRtwAoSOArfk7cuYvFXytxfVrdX7yxoUmK7pPITLk5jYh2F8knCwS7LjgYL8u1eidPlKKV6Ikqq0ODqQ==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.4.tgz", + "integrity": "sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -4597,9 +5045,10 @@ } }, "node_modules/@wry/equality": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.3.tgz", - "integrity": "sha512-avR+UXdSrsF2v8vIqIgmeTY0UR91UT+IyablCyKe/uk22uOJ8fusKZnH9JH9e1/EtLeNJBtagNmL3eJdnOV53g==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.7.tgz", + "integrity": "sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -4608,9 +5057,10 @@ } }, "node_modules/@wry/trie": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.3.2.tgz", - "integrity": "sha512-yRTyhWSls2OY/pYLfwff867r8ekooZ4UI+/gxot5Wj8EFwSf2rG+n+Mo/6LoLQm1TKA4GRj2+LCpbfS937dClQ==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.5.0.tgz", + "integrity": "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -4621,22 +5071,27 @@ "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "license": "BSD-3-Clause" }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -4646,9 +5101,10 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -4660,6 +5116,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "license": "MIT", "dependencies": { "acorn": "^7.1.1", "acorn-walk": "^7.1.1" @@ -4669,6 +5126,7 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -4676,10 +5134,11 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", "peerDependencies": { "acorn": "^8" } @@ -4688,43 +5147,25 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "dependencies": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - } - }, - "node_modules/acorn-node/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/acorn-walk": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/address": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", - "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -4733,6 +5174,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "regex-parser": "^2.2.11" @@ -4745,6 +5187,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", "dependencies": { "debug": "4" }, @@ -4756,6 +5199,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4771,6 +5215,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -4784,14 +5229,15 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -4801,12 +5247,14 @@ "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } @@ -4815,6 +5263,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -4825,6 +5274,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-html": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz", + "integrity": "sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg==", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -4832,6 +5293,7 @@ "engines": [ "node >= 0.8.0" ], + "license": "Apache-2.0", "bin": { "ansi-html": "bin/ansi-html" } @@ -4840,25 +5302,37 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4870,42 +5344,60 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "license": "Apache-2.0", "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" }, "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -4919,18 +5411,60 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -4941,13 +5475,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -4958,14 +5493,17 @@ } }, "node_modules/array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.7.tgz", + "integrity": "sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", "es-array-method-boxes-properly": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "is-string": "^1.0.7" }, "engines": { @@ -4976,49 +5514,80 @@ } }, "node_modules/array.prototype.tosorted": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", - "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.1.3" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" }, "node_modules/ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "license": "MIT" }, "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", "engines": { "node": ">= 4.0.0" } }, "node_modules/autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "funding": [ { "type": "opencollective", @@ -5027,14 +5596,19 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", - "fraction.js": "^4.2.0", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -5048,9 +5622,13 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -5059,22 +5637,28 @@ } }, "node_modules/axe-core": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", - "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", + "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", + "license": "MPL-2.0", "engines": { "node": ">=4" } }, "node_modules/axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } }, "node_modules/babel-jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "license": "MIT", "dependencies": { "@jest/transform": "^27.5.1", "@jest/types": "^27.5.1", @@ -5092,74 +5676,36 @@ "@babel/core": "^7.8.0" } }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/babel-jest/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/babel-jest/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "@types/yargs-parser": "*" } }, "node_modules/babel-loader": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "license": "MIT", "dependencies": { "find-cache-dir": "^3.3.1", "loader-utils": "^2.0.0", @@ -5178,6 +5724,7 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.5", "ajv": "^6.12.4", @@ -5195,6 +5742,7 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -5210,6 +5758,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -5224,6 +5773,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", @@ -5238,76 +5788,86 @@ "version": "0.3.8", "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "license": "MIT", "peerDependencies": { "@babel/core": "^7.1.0" } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", - "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", + "license": "MIT" }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -5317,6 +5877,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^27.5.1", "babel-preset-current-node-syntax": "^1.0.0" @@ -5332,6 +5893,7 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", "@babel/plugin-proposal-class-properties": "^7.16.0", @@ -5354,26 +5916,31 @@ "node_modules/backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", + "license": "MIT" }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "license": "MIT" }, "node_modules/bfj": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", - "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", + "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", + "license": "MIT", "dependencies": { - "bluebird": "^3.5.5", - "check-types": "^11.1.1", + "bluebird": "^3.7.2", + "check-types": "^11.2.3", "hoopy": "^0.1.4", + "jsonpath": "^1.1.1", "tryer": "^1.0.1" }, "engines": { @@ -5384,27 +5951,34 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "license": "MIT", "engines": { "node": "*" } }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -5428,6 +6002,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -5436,6 +6011,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -5444,6 +6020,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -5454,15 +6031,15 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/bonjour-service": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.14.tgz", - "integrity": "sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "license": "MIT", "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } @@ -5470,23 +6047,26 @@ "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -5495,12 +6075,13 @@ "node_modules/browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "license": "BSD-2-Clause" }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "funding": [ { "type": "opencollective", @@ -5515,11 +6096,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -5532,6 +6114,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -5539,12 +6122,14 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -5556,17 +6141,25 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5576,6 +6169,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", "engines": { "node": ">=6" } @@ -5584,6 +6178,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" @@ -5593,6 +6188,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -5604,6 +6200,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "license": "MIT", "engines": { "node": ">= 6" } @@ -5612,6 +6209,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "license": "MIT", "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", @@ -5620,9 +6218,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001605", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz", - "integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==", + "version": "1.0.30001657", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001657.tgz", + "integrity": "sha512-DPbJAlP8/BAXy3IgiWmZKItubb3TYGP0WscQQlVGIfT4s/YlFYVuJgyOsQNP7rJRChx/qdMeLJQJP0Sgg2yjNA==", "funding": [ { "type": "opencollective", @@ -5636,52 +6234,54 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/check-types": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz", - "integrity": "sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA==" + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==", + "license": "MIT" }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -5694,6 +6294,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -5702,6 +6305,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -5710,30 +6314,40 @@ } }, "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/ci-info": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", - "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.0.tgz", + "integrity": "sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g==", + "license": "MIT" }, "node_modules/clean-css": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", - "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "license": "MIT", "dependencies": { "source-map": "~0.6.0" }, @@ -5745,6 +6359,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -5753,6 +6368,7 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -5763,6 +6379,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -5772,6 +6389,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "license": "MIT", "dependencies": { "@types/q": "^1.5.1", "chalk": "^2.4.1", @@ -5781,38 +6399,118 @@ "node": ">= 4.0" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } }, - "node_modules/color-convert": { + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, - "node_modules/color-name": { + "node_modules/coa/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/coa/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coa/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "license": "MIT" }, "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -5824,19 +6522,16 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", "engines": { "node": ">= 12" } }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, "node_modules/common-tags": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -5844,12 +6539,14 @@ "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "license": "MIT" }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -5861,6 +6558,7 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -5878,6 +6576,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -5885,27 +6584,32 @@ "node_modules/compression/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/compression/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" }, "node_modules/confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "license": "MIT" }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "license": "MIT", "engines": { "node": ">=0.8" } @@ -5914,6 +6618,7 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -5925,19 +6630,22 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -5945,24 +6653,27 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" }, "node_modules/core-js": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", - "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz", + "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==", "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "license": "MIT", "dependencies": { - "browserslist": "^4.21.4" + "browserslist": "^4.23.3" }, "funding": { "type": "opencollective", @@ -5970,10 +6681,11 @@ } }, "node_modules/core-js-pure": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", - "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.1.tgz", + "integrity": "sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==", "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -5982,12 +6694,14 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -6003,6 +6717,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -6016,6 +6731,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "license": "MIT", "engines": { "node": ">=8" } @@ -6024,6 +6740,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -6038,9 +6755,10 @@ } }, "node_modules/css-declaration-sorter": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", - "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "license": "ISC", "engines": { "node": "^10 || ^12 || >=14" }, @@ -6052,6 +6770,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -6066,18 +6785,19 @@ } }, "node_modules/css-loader": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.2.tgz", - "integrity": "sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.18", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" + "semver": "^7.5.4" }, "engines": { "node": ">= 12.13.0" @@ -6087,13 +6807,23 @@ "url": "https://opencollective.com/webpack" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/css-minimizer-webpack-plugin": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "license": "MIT", "dependencies": { "cssnano": "^5.0.6", "jest-worker": "^27.0.2", @@ -6127,59 +6857,11 @@ } } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -6188,6 +6870,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", + "license": "CC0-1.0", "bin": { "css-prefers-color-scheme": "dist/cli.cjs" }, @@ -6202,6 +6885,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", @@ -6216,12 +6900,14 @@ "node_modules/css-select-base-adapter": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "license": "MIT" }, "node_modules/css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "license": "MIT", "dependencies": { "mdn-data": "2.0.4", "source-map": "^0.6.1" @@ -6234,6 +6920,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -6242,6 +6929,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -6252,21 +6940,30 @@ "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "license": "MIT" }, "node_modules/cssdb": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.2.0.tgz", - "integrity": "sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz", + "integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ], + "license": "CC0-1.0" }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -6275,11 +6972,12 @@ } }, "node_modules/cssnano": { - "version": "5.1.14", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", - "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "license": "MIT", "dependencies": { - "cssnano-preset-default": "^5.2.13", + "cssnano-preset-default": "^5.2.14", "lilconfig": "^2.0.3", "yaml": "^1.10.2" }, @@ -6295,21 +6993,22 @@ } }, "node_modules/cssnano-preset-default": { - "version": "5.2.13", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", - "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "license": "MIT", "dependencies": { "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", + "postcss-colormin": "^5.3.1", "postcss-convert-values": "^5.1.3", "postcss-discard-comments": "^5.1.2", "postcss-discard-duplicates": "^5.1.0", "postcss-discard-empty": "^5.1.1", "postcss-discard-overridden": "^5.1.0", "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.3", + "postcss-merge-rules": "^5.1.4", "postcss-minify-font-values": "^5.1.0", "postcss-minify-gradients": "^5.1.1", "postcss-minify-params": "^5.1.4", @@ -6324,7 +7023,7 @@ "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.1", + "postcss-reduce-initial": "^5.1.2", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", "postcss-unique-selectors": "^5.1.1" @@ -6340,6 +7039,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -6351,6 +7051,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "license": "MIT", "dependencies": { "css-tree": "^1.1.2" }, @@ -6362,6 +7063,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" @@ -6373,12 +7075,14 @@ "node_modules/csso/node_modules/mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "license": "CC0-1.0" }, "node_modules/csso/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -6386,12 +7090,14 @@ "node_modules/cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "license": "MIT" }, "node_modules/cssstyle": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "license": "MIT", "dependencies": { "cssom": "~0.3.6" }, @@ -6402,22 +7108,26 @@ "node_modules/cssstyle/node_modules/cssom": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "license": "MIT" }, "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "license": "BSD-2-Clause" }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "license": "MIT", "dependencies": { "abab": "^2.0.3", "whatwg-mimetype": "^2.3.0", @@ -6427,10 +7137,62 @@ "node": ">=10" } }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -6444,54 +7206,60 @@ } }, "node_modules/decimal.js": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", - "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==" + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "license": "MIT" }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "license": "MIT" }, "node_modules/deep-equal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.1.0.tgz", - "integrity": "sha512-2pxgvWu3Alv1PoWEyVg7HS8YhGlUFUV7N5oOvfL6d+7xAmLSemMwv/c8Zv/i9KFzxV5Kt5CAvQc70fLwVuf4UA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "es-get-iterator": "^1.1.2", - "get-intrinsic": "^1.1.3", + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", "is-date-object": "^1.0.5", "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", "isarray": "^2.0.5", "object-is": "^1.1.5", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", + "regexp.prototype.flags": "^1.5.1", "side-channel": "^1.0.4", "which-boxed-primitive": "^1.0.2", "which-collection": "^1.0.1", - "which-typed-array": "^1.1.8" + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/deep-equal/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "license": "MIT" }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6500,6 +7268,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "license": "BSD-2-Clause", "dependencies": { "execa": "^5.0.0" }, @@ -6507,19 +7276,39 @@ "node": ">= 10" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -6530,18 +7319,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/defined": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -6550,14 +7332,25 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -6567,6 +7360,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "license": "MIT", "engines": { "node": ">=8" } @@ -6574,12 +7368,14 @@ "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT" }, "node_modules/detect-port-alt": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "license": "MIT", "dependencies": { "address": "^1.0.1", "debug": "^2.6.0" @@ -6596,6 +7392,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -6603,41 +7400,29 @@ "node_modules/detect-port-alt/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", - "dependencies": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - }, - "bin": { - "detective": "bin/detective.js" - }, - "engines": { - "node": ">=0.8.0" - } + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "license": "Apache-2.0" }, "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "license": "MIT", "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -6648,17 +7433,14 @@ "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" }, "node_modules/dns-packet": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", - "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -6670,6 +7452,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -6678,14 +7461,16 @@ } }, "node_modules/dom-accessibility-api": { - "version": "0.5.14", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", - "integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==" + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "license": "MIT" }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "license": "MIT", "dependencies": { "utila": "~0.4" } @@ -6694,6 +7479,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -6712,12 +7498,15 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ] + ], + "license": "BSD-2-Clause" }, "node_modules/domexception": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "deprecated": "Use your platform's native DOMException instead", + "license": "MIT", "dependencies": { "webidl-conversions": "^5.0.0" }, @@ -6729,6 +7518,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "license": "BSD-2-Clause", "engines": { "node": ">=8" } @@ -6737,6 +7527,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" }, @@ -6751,6 +7542,7 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -6764,6 +7556,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -6773,6 +7566,7 @@ "version": "10.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "license": "BSD-2-Clause", "engines": { "node": ">=10" } @@ -6780,22 +7574,32 @@ "node_modules/dotenv-expand": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "license": "BSD-2-Clause" }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" }, @@ -6807,14 +7611,16 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.724", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.724.tgz", - "integrity": "sha512-RTRvkmRkGhNBPPpdrgtDKvmOEYTrPlXDfc0J/Nfq5s29tEahAwhiX4mmhNzj6febWMleulxVYPh7QwCSL/EldA==" + "version": "1.5.14", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.14.tgz", + "integrity": "sha512-bEfPECb3fJ15eaDnu9LEJ2vPGD6W1vt7vZleSVyFhYuMIKm3vz/g9lt7IvEzgdwj58RjbPKUF2rXTCN/UW47tQ==", + "license": "ISC" }, "node_modules/emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -6825,12 +7631,14 @@ "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" }, "node_modules/emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "license": "MIT", "engines": { "node": ">= 4" } @@ -6839,14 +7647,16 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/enhanced-resolve": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", - "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -6859,6 +7669,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -6867,6 +7678,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } @@ -6875,39 +7687,63 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", "dependencies": { "stackframe": "^1.3.4" } }, "node_modules/es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -6919,48 +7755,121 @@ "node_modules/es-array-method-boxes-properly": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } }, "node_modules/es-get-iterator": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", - "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.0", - "has-symbols": "^1.0.1", - "is-arguments": "^1.1.0", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", "is-map": "^2.0.2", "is-set": "^2.0.2", - "is-string": "^1.0.5", - "isarray": "^2.0.5" + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-get-iterator/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/es-module-lexer": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz", - "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==" + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "license": "MIT", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -6974,9 +7883,10 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -6984,25 +7894,30 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" + "esutils": "^2.0.2" }, "bin": { "escodegen": "bin/escodegen.js", @@ -7015,105 +7930,59 @@ "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/escodegen/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", - "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "license": "MIT", "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", - "grapheme-splitter": "^1.0.4", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -7130,6 +7999,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", "@babel/eslint-parser": "^7.16.3", @@ -7154,26 +8024,30 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "license": "MIT", "dependencies": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz", + "integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==", + "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -7190,6 +8064,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -7198,6 +8073,7 @@ "version": "8.0.3", "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "license": "BSD-3-Clause", "dependencies": { "lodash": "^4.17.21", "string-natural-compare": "^3.0.1" @@ -7212,23 +8088,29 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", + "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", + "license": "MIT", "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.9.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -7238,17 +8120,19 @@ } }, "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -7256,15 +8140,20 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } }, "node_modules/eslint-plugin-jest": { "version": "25.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "license": "MIT", "dependencies": { "@typescript-eslint/experimental-utils": "^5.0.0" }, @@ -7285,71 +8174,81 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", - "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.0.tgz", + "integrity": "sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.18.9", - "aria-query": "^4.2.2", - "array-includes": "^3.1.5", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.4.3", - "axobject-query": "^2.2.0", + "aria-query": "~5.1.3", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.3.2", - "language-tags": "^1.0.5", + "es-iterator-helpers": "^1.0.19", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", "minimatch": "^3.1.2", - "semver": "^6.3.0" + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.0" }, "engines": { "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" } }, "node_modules/eslint-plugin-react": { - "version": "7.31.11", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", - "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", + "version": "7.35.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz", + "integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==", + "license": "MIT", "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.8" + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -7361,6 +8260,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -7369,11 +8269,12 @@ } }, "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", - "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "license": "MIT", "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -7388,16 +8289,18 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/eslint-plugin-testing-library": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.9.1.tgz", - "integrity": "sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ==", + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", + "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", + "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^5.13.0" + "@typescript-eslint/utils": "^5.58.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0", @@ -7408,54 +8311,38 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "engines": { - "node": ">=10" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-webpack-plugin": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "license": "MIT", "dependencies": { "@types/eslint": "^7.29.0 || ^8.4.1", "jest-worker": "^28.0.2", @@ -7475,44 +8362,11 @@ "webpack": "^5.0.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -7522,33 +8376,11 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/eslint-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -7559,71 +8391,33 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -7634,18 +8428,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/eslint/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -7653,21 +8440,56 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -7676,13 +8498,14 @@ } }, "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -7695,6 +8518,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -7704,9 +8528,10 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -7718,6 +8543,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -7729,6 +8555,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -7736,12 +8563,14 @@ "node_modules/estree-walker": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -7750,19 +8579,22 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "license": "MIT" }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", "engines": { "node": ">=0.8.x" } @@ -7771,6 +8603,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -7798,23 +8631,26 @@ } }, "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "license": "MIT", "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/express": { "version": "4.19.2", "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -7852,15 +8688,11 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -7868,17 +8700,20 @@ "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -7894,6 +8729,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -7904,22 +8740,32 @@ "node_modules/fast-json-patch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", + "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "license": "MIT" }, "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -7928,6 +8774,7 @@ "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -7939,6 +8786,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } @@ -7947,6 +8795,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -7958,6 +8807,7 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" @@ -7973,10 +8823,29 @@ "webpack": "^4.0.0 || ^5.0.0" } }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", "dependencies": { "minimatch": "^5.0.1" } @@ -7985,14 +8854,16 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.1.tgz", - "integrity": "sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -8004,14 +8875,16 @@ "version": "8.0.7", "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "license": "BSD-3-Clause", "engines": { "node": ">= 0.4.0" } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -8023,6 +8896,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -8040,6 +8914,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -8047,12 +8922,14 @@ "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -8066,26 +8943,26 @@ } }, "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", "dependencies": { - "locate-path": "^6.0.0", + "locate-path": "^5.0.0", "path-exists": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "license": "MIT", "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { @@ -8093,20 +8970,22 @@ } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -8120,14 +8999,44 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz", - "integrity": "sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.8.3", "@types/json-schema": "^7.0.5", @@ -8162,55 +9071,11 @@ } } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.1.0", @@ -8226,6 +9091,7 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -8236,18 +9102,11 @@ "node": ">=10" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.4", "ajv": "^6.12.2", @@ -8261,21 +9120,11 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -8284,6 +9133,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -8297,26 +9147,29 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", "engines": { "node": "*" }, "funding": { "type": "patreon", - "url": "https://www.patreon.com/infusion" + "url": "https://github.com/sponsors/rawify" } }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8325,6 +9178,7 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -8335,20 +9189,23 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "license": "Unlicense" }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -8358,19 +9215,24 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -8383,6 +9245,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8391,6 +9254,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -8399,18 +9263,25 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8419,12 +9290,14 @@ "node_modules/get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "license": "ISC" }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -8433,6 +9306,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -8441,12 +9315,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -8459,6 +9335,8 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -8478,6 +9356,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -8488,12 +9367,14 @@ "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "license": "MIT", "dependencies": { "global-prefix": "^3.0.0" }, @@ -8505,6 +9386,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "license": "MIT", "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -8518,6 +9400,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -8529,14 +9412,32 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -8556,6 +9457,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -8566,17 +9468,20 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "license": "MIT" }, "node_modules/graphql": { - "version": "16.8.1", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", - "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", + "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -8585,6 +9490,7 @@ "version": "2.12.6", "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" }, @@ -8596,9 +9502,13 @@ } }, "node_modules/graphql-ws": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.11.2.tgz", - "integrity": "sha512-4EiZ3/UXYcjm+xFGP544/yW1+DVI8ZpKASFbzrV5EDTFWJp0ZvLl4Dy2fSZAzz9imKp5pZMIcjB0x/H69Pv/6w==", + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz", + "integrity": "sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==", + "license": "MIT", + "workspaces": [ + "website" + ], "engines": { "node": ">=10" }, @@ -8610,6 +9520,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "license": "MIT", "dependencies": { "duplexer": "^0.1.2" }, @@ -8623,46 +9534,52 @@ "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "license": "MIT" }, "node_modules/harmony-reflect": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", + "license": "(Apache-2.0 OR MPL-1.1)" }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8672,6 +9589,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8680,11 +9598,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -8693,10 +9612,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", "bin": { "he": "bin/he" } @@ -8705,19 +9637,16 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" } }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "license": "MIT", "engines": { "node": ">= 6.0.0" } @@ -8726,6 +9655,7 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "license": "MIT", "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -8733,10 +9663,17 @@ "wbuf": "^1.1.0" } }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8750,12 +9687,14 @@ "node_modules/hpack.js/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -8764,6 +9703,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "license": "MIT", "dependencies": { "whatwg-encoding": "^1.0.5" }, @@ -8772,19 +9712,32 @@ } }, "node_modules/html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "license": "MIT" }, "node_modules/html-minifier-terser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "license": "MIT", "dependencies": { "camel-case": "^4.1.2", "clean-css": "^5.2.2", @@ -8802,9 +9755,10 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "license": "MIT", "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", @@ -8820,7 +9774,16 @@ "url": "https://opencollective.com/html-webpack-plugin" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/htmlparser2": { @@ -8834,6 +9797,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", @@ -8844,12 +9808,14 @@ "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "license": "MIT" }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -8864,12 +9830,14 @@ "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "license": "MIT" }, "node_modules/http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -8883,6 +9851,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "license": "MIT", "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -8896,6 +9865,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -8915,10 +9885,17 @@ } } }, + "node_modules/http-proxy/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", "dependencies": { "agent-base": "6", "debug": "4" @@ -8931,6 +9908,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } @@ -8939,6 +9917,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -8950,6 +9929,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -8960,12 +9940,14 @@ "node_modules/idb": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" }, "node_modules/identity-obj-proxy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "license": "MIT", "dependencies": { "harmony-reflect": "^1.4.6" }, @@ -8974,17 +9956,19 @@ } }, "node_modules/ignore": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", - "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/immer": { - "version": "9.0.16", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz", - "integrity": "sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ==", + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -8994,6 +9978,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -9009,14 +9994,16 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -9035,6 +10022,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -9043,6 +10031,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -9051,6 +10040,8 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -9059,20 +10050,23 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" }, "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -9080,9 +10074,10 @@ } }, "node_modules/ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "license": "MIT", "engines": { "node": ">= 10" } @@ -9091,6 +10086,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -9102,15 +10098,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -9122,6 +10151,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -9133,6 +10163,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -9148,6 +10179,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9156,11 +10188,30 @@ } }, "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "license": "MIT", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9170,6 +10221,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -9184,6 +10236,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -9198,14 +10251,28 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -9214,14 +10281,31 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -9230,9 +10314,13 @@ } }, "node_modules/is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9240,12 +10328,14 @@ "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "license": "MIT" }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9257,6 +10347,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -9265,6 +10356,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -9279,6 +10371,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9287,6 +10380,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -9295,6 +10389,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -9305,12 +10400,14 @@ "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "license": "MIT" }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -9326,6 +10423,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9334,24 +10432,33 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9361,6 +10468,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -9372,6 +10480,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -9386,6 +10495,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -9397,15 +10507,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -9417,12 +10524,17 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" }, "node_modules/is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9431,6 +10543,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -9439,12 +10552,16 @@ } }, "node_modules/is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9454,6 +10571,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -9462,19 +10580,22 @@ } }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "license": "BSD-3-Clause", "engines": { "node": ">=8" } @@ -9483,6 +10604,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -9498,46 +10620,45 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { + "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -9551,14 +10672,16 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -9570,17 +10693,47 @@ "node_modules/iterall": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" + "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", + "license": "MIT" + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } }, "node_modules/jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" + "filelist": "^1.0.4", + "minimatch": "^3.1.2" }, "bin": { "jake": "bin/cli.js" @@ -9589,74 +10742,11 @@ "node": ">=10" } }, - "node_modules/jake/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jake/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jake/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jake/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jake/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "license": "MIT", "dependencies": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", @@ -9681,6 +10771,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "execa": "^5.0.0", @@ -9690,10 +10781,36 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-changed-files/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, "node_modules/jest-circus": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", "@jest/test-result": "^27.5.1", @@ -9719,74 +10836,136 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-circus/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-circus/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/jest-circus/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, + "node_modules/jest-circus/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "license": "MIT", "engines": { - "node": ">=7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-circus/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-circus/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-cli": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "license": "MIT", "dependencies": { "@jest/core": "^27.5.1", "@jest/test-result": "^27.5.1", @@ -9816,74 +10995,53 @@ } } }, - "node_modules/jest-cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-cli/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-cli/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/jest-cli/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-cli/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-cli/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-config": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "license": "MIT", "dependencies": { "@babel/core": "^7.8.0", "@jest/test-sequencer": "^27.5.1", @@ -9922,152 +11080,109 @@ } } }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-config/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff": { + "node_modules/jest-config/node_modules/@jest/types": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-config/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-config/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" }, "node_modules/jest-docblock": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -10079,6 +11194,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "chalk": "^4.0.0", @@ -10090,74 +11206,62 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-each/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-each/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/jest-each/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "license": "MIT", "engines": { - "node": ">=7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-each/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-each/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-each/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-environment-jsdom": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", "@jest/fake-timers": "^27.5.1", @@ -10171,10 +11275,53 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-environment-jsdom/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, "node_modules/jest-environment-node": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", "@jest/fake-timers": "^27.5.1", @@ -10187,18 +11334,62 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-get-type": { + "node_modules/jest-environment-node/node_modules/@jest/types": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-environment-node/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-environment-node/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/jest-haste-map": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "@types/graceful-fs": "^4.1.2", @@ -10220,10 +11411,53 @@ "fsevents": "^2.3.2" } }, + "node_modules/jest-haste-map/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-haste-map/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, "node_modules/jest-jasmine2": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", "@jest/source-map": "^27.5.1", @@ -10247,75 +11481,63 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-jasmine2/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-leak-detector": { + "node_modules/jest-jasmine2/node_modules/@jest/types": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-jasmine2/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", "jest-get-type": "^27.5.1", "pretty-format": "^27.5.1" }, @@ -10323,10 +11545,20 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils": { + "node_modules/jest-jasmine2/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "jest-diff": "^27.5.1", @@ -10337,74 +11569,11 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util": { + "node_modules/jest-jasmine2/node_modules/jest-message-util": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^27.5.1", @@ -10420,74 +11589,149 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-jasmine2/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "license": "MIT", + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=7.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" }, "node_modules/jest-mock": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "@types/node": "*" @@ -10496,10 +11740,36 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-mock/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -10516,6 +11786,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "license": "MIT", "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } @@ -10524,6 +11795,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "chalk": "^4.0.0", @@ -10544,6 +11816,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "jest-regex-util": "^27.5.1", @@ -10553,74 +11826,78 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-resolve/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-resolve-dependencies/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/jest-resolve/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-resolve/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-resolve/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-resolve/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-resolve/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-resolve/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-runner": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "license": "MIT", "dependencies": { "@jest/console": "^27.5.1", "@jest/environment": "^27.5.1", @@ -10648,74 +11925,73 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-runner/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-runner/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/jest-runner/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-runner/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-runner/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-runner/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-runtime": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", "@jest/fake-timers": "^27.5.1", @@ -10744,74 +12020,73 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runtime/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-runtime/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-runtime/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/jest-runtime/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-runtime/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runtime/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-runtime/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-runtime/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-serializer": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "license": "MIT", "dependencies": { "@types/node": "*", "graceful-fs": "^4.2.9" @@ -10824,6 +12099,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "license": "MIT", "dependencies": { "@babel/core": "^7.7.2", "@babel/generator": "^7.7.2", @@ -10852,74 +12128,119 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-snapshot/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-snapshot/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/jest-snapshot/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" }, "engines": { - "node": ">=7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-snapshot/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-util": { + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-util": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "@types/node": "*", @@ -10932,74 +12253,28 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-validate": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", "camelcase": "^6.2.0", @@ -11012,74 +12287,45 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-validate/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-validate/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "license": "MIT", "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-watch-typeahead": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", + "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.1", "chalk": "^4.0.0", @@ -11100,6 +12346,7 @@ "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "license": "MIT", "dependencies": { "@jest/types": "^28.1.3", "@types/node": "*", @@ -11116,14 +12363,28 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/jest-watch-typeahead/node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "license": "MIT", "dependencies": { "@jest/console": "^28.1.3", "@jest/types": "^28.1.3", @@ -11138,6 +12399,7 @@ "version": "28.1.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "license": "MIT", "dependencies": { "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -11150,63 +12412,29 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { - "version": "17.0.15", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz", - "integrity": "sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==", - "dependencies": { - "@types/yargs-parser": "*" - } + "node_modules/jest-watch-typeahead/node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", + "license": "MIT" }, "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-watch-typeahead/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "node_modules/jest-watch-typeahead/node_modules/emittery": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -11214,18 +12442,11 @@ "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/jest-watch-typeahead/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^28.1.3", @@ -11245,6 +12466,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", "engines": { "node": ">=8" } @@ -11253,6 +12475,7 @@ "version": "28.0.2", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "license": "MIT", "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } @@ -11261,6 +12484,7 @@ "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "license": "MIT", "dependencies": { "@jest/types": "^28.1.3", "@types/node": "*", @@ -11277,6 +12501,7 @@ "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "license": "MIT", "dependencies": { "@jest/test-result": "^28.1.3", "@jest/types": "^28.1.3", @@ -11295,6 +12520,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -11307,6 +12533,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11318,6 +12545,7 @@ "version": "28.1.3", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "license": "MIT", "dependencies": { "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", @@ -11328,26 +12556,17 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-watch-typeahead/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" }, "node_modules/jest-watch-typeahead/node_modules/slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -11359,6 +12578,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "license": "MIT", "dependencies": { "char-regex": "^2.0.0", "strip-ansi": "^7.0.1" @@ -11374,14 +12594,16 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "license": "MIT", "engines": { "node": ">=12.20" } }, "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -11396,6 +12618,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -11403,21 +12626,11 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/jest-watch-typeahead/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-watcher": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "license": "MIT", "dependencies": { "@jest/test-result": "^27.5.1", "@jest/types": "^27.5.1", @@ -11431,74 +12644,53 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-watcher/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/jest-watcher/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/jest-watcher/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/yargs-parser": "*" } }, - "node_modules/jest-watcher/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/jest-watcher/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watcher/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-watcher/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -11508,18 +12700,11 @@ "node": ">= 10.13.0" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -11530,24 +12715,26 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" } }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -11560,6 +12747,7 @@ "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "license": "MIT", "dependencies": { "abab": "^2.0.5", "acorn": "^8.2.4", @@ -11605,6 +12793,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -11612,30 +12801,41 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -11647,6 +12847,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -11654,30 +12855,67 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "license": "MIT", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath/node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/jsonpointer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/jsx-ast-utils": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", - "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "license": "MIT", "dependencies": { - "array-includes": "^3.1.5", - "object.assign": "^4.1.3" + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" }, "engines": { "node": ">=4.0" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11686,35 +12924,53 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/klona": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", - "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/language-subtag-registry": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", - "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "license": "CC0-1.0" }, "node_modules/language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "license": "MIT", "dependencies": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" } }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", "engines": { "node": ">=6" } @@ -11723,6 +12979,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -11732,9 +12989,10 @@ } }, "node_modules/lilconfig": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "license": "MIT", "engines": { "node": ">=10" } @@ -11742,12 +13000,14 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "license": "MIT", "engines": { "node": ">=6.11.5" } @@ -11756,6 +13016,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -11766,53 +13027,58 @@ } }, "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", "dependencies": { - "p-locate": "^5.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "license": "MIT" }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -11824,25 +13090,25 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "license": "MIT", "bin": { "lz-string": "bin/bin.js" } @@ -11851,6 +13117,7 @@ "version": "0.25.9", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "license": "MIT", "dependencies": { "sourcemap-codec": "^1.4.8" } @@ -11859,6 +13126,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -11873,6 +13141,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -11881,6 +13150,7 @@ "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } @@ -11888,22 +13158,25 @@ "node_modules/mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "license": "CC0-1.0" }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/memfs": { - "version": "3.4.12", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.12.tgz", - "integrity": "sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "license": "Unlicense", "dependencies": { - "fs-monkey": "^1.0.3" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" @@ -11912,17 +13185,20 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "license": "MIT" }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", "engines": { "node": ">= 8" } @@ -11931,16 +13207,18 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -11951,6 +13229,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -11962,6 +13241,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -11970,6 +13250,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -11981,6 +13262,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", "engines": { "node": ">=6" } @@ -11989,16 +13271,19 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/mini-css-extract-plugin": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.1.tgz", - "integrity": "sha512-viOoaUFy+Z2w43VsGPbtfwFrr0tKwDctK9dUofG5MBViYhD1noGFUzzDIVw0KPwCGUP+c7zqLxm+acuQs7zLzw==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.1.tgz", + "integrity": "sha512-+Vyi+GCCOHnrJ2VPS+6aPoXN2k2jgUzDRhTFLjjTBn23qyXJXkjUWQgTL+mXpF5/A8ixLdCc6kWsoeOjKGejKQ==", + "license": "MIT", "dependencies": { - "schema-utils": "^4.0.0" + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" }, "engines": { "node": ">= 12.13.0" @@ -12011,64 +13296,17 @@ "webpack": "^5.0.0" } }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -12077,17 +13315,28 @@ } }, "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -12098,12 +13347,14 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -12112,10 +13363,28 @@ "multicast-dns": "cli.js" } }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -12126,17 +13395,20 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT" }, "node_modules/natural-compare-lite": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -12144,12 +13416,14 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" @@ -12159,6 +13433,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } @@ -12166,17 +13441,20 @@ "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12185,6 +13463,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12193,6 +13472,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -12204,6 +13484,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -12215,6 +13496,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" }, @@ -12223,14 +13505,16 @@ } }, "node_modules/nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", + "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", + "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12239,25 +13523,31 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -12270,17 +13560,19 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -12292,26 +13584,29 @@ } }, "node_modules/object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -12321,14 +13616,18 @@ } }, "node_modules/object.getownpropertydescriptors": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", - "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz", + "integrity": "sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==", + "license": "MIT", "dependencies": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "gopd": "^1.0.1", + "safe-array-concat": "^1.1.2" }, "engines": { "node": ">= 0.8" @@ -12337,26 +13636,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.hasown": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", - "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "license": "MIT", "dependencies": { - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.4" } }, "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -12368,12 +13670,14 @@ "node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "license": "MIT" }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -12385,6 +13689,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -12393,6 +13698,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -12401,6 +13707,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -12412,9 +13719,10 @@ } }, "node_modules/open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -12428,62 +13736,78 @@ } }, "node_modules/optimism": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.16.2.tgz", - "integrity": "sha512-zWNbgWj+3vLEjZNIh/okkY2EUfX+vB9TJopzIZwT1xxaMqC5hRLLraePod4c5n4He08xuXNH+zhKFFCu390wiQ==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.0.tgz", + "integrity": "sha512-tGn8+REwLRNFnb9WmcY5IfpOqeX2kpaYJ1s6Ae3mn12AeydLkR3j+jSCmVQFoXqU8D41PAJ1RG1rCRNWmNZVmQ==", + "license": "MIT", "dependencies": { + "@wry/caches": "^1.0.0", "@wry/context": "^0.7.0", - "@wry/trie": "^0.3.0" + "@wry/trie": "^0.4.3", + "tslib": "^2.3.0" + } + }, + "node_modules/optimism/node_modules/@wry/trie": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.4.3.tgz", + "integrity": "sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", "dependencies": { - "yocto-queue": "^0.1.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", "dependencies": { - "p-limit": "^3.0.2" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/p-retry": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" @@ -12496,14 +13820,22 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "license": "BlueOak-1.0.0" + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -12513,6 +13845,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -12524,6 +13857,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -12540,12 +13874,14 @@ "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "license": "MIT" }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -12554,6 +13890,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -12563,6 +13900,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", "engines": { "node": ">=8" } @@ -12571,6 +13909,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -12579,6 +13918,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", "engines": { "node": ">=8" } @@ -12586,17 +13926,42 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", "engines": { "node": ">=8" } @@ -12604,17 +13969,20 @@ "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -12626,14 +13994,16 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "license": "MIT", "engines": { "node": ">= 6" } @@ -12642,6 +14012,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -12649,58 +14020,11 @@ "node": ">=8" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "license": "MIT", "dependencies": { "find-up": "^3.0.0" }, @@ -12712,6 +14036,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "license": "MIT", "dependencies": { "locate-path": "^3.0.0" }, @@ -12723,6 +14048,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "license": "MIT", "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -12731,24 +14057,11 @@ "node": ">=6" } }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pkg-up/node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "license": "MIT", "dependencies": { "p-limit": "^2.0.0" }, @@ -12760,14 +14073,24 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "version": "8.4.45", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", + "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", "funding": [ { "type": "opencollective", @@ -12776,12 +14099,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -12791,6 +14119,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -12809,6 +14138,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "license": "CC0-1.0", "engines": { "node": ">=8" }, @@ -12821,6 +14151,7 @@ "version": "8.2.4", "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.9", "postcss-value-parser": "^4.2.0" @@ -12833,6 +14164,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12847,6 +14179,7 @@ "version": "4.2.4", "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12865,6 +14198,7 @@ "version": "8.0.4", "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12883,6 +14217,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12898,11 +14233,12 @@ } }, "node_modules/postcss-colormin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", - "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "license": "MIT", "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "colord": "^2.9.1", "postcss-value-parser": "^4.2.0" @@ -12918,6 +14254,7 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" @@ -12933,6 +14270,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12951,6 +14289,7 @@ "version": "12.1.11", "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12969,6 +14308,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -12987,6 +14327,7 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -13005,6 +14346,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -13016,6 +14358,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -13027,6 +14370,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -13038,6 +14382,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -13049,6 +14394,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -13068,6 +14414,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13082,6 +14429,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "license": "MIT", "peerDependencies": { "postcss": "^8.1.4" } @@ -13090,6 +14438,7 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -13104,6 +14453,7 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -13118,6 +14468,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "license": "MIT", "peerDependencies": { "postcss": "^8.1.0" } @@ -13126,6 +14477,7 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", + "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" }, @@ -13141,6 +14493,7 @@ "version": "4.0.7", "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13156,16 +14509,17 @@ } }, "node_modules/postcss-import": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", - "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "engines": { - "node": ">=10.0.0" + "node": ">=14.0.0" }, "peerDependencies": { "postcss": "^8.0.0" @@ -13175,14 +14529,16 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "license": "MIT", "peerDependencies": { "postcss": "^8.0.0" } }, "node_modules/postcss-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", - "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" }, @@ -13194,13 +14550,14 @@ "url": "https://opencollective.com/postcss/" }, "peerDependencies": { - "postcss": "^8.3.3" + "postcss": "^8.4.21" } }, "node_modules/postcss-lab-function": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -13217,19 +14574,26 @@ } }, "node_modules/postcss-load-config": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", - "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" }, "engines": { - "node": ">= 10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "node": ">= 14" }, "peerDependencies": { "postcss": ">=8.0.9", @@ -13244,10 +14608,35 @@ } } }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/postcss-loader": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", + "license": "MIT", "dependencies": { "cosmiconfig": "^7.0.0", "klona": "^2.0.5", @@ -13269,6 +14658,7 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" }, @@ -13280,6 +14670,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -13291,6 +14682,7 @@ "version": "5.1.7", "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^5.1.1" @@ -13303,9 +14695,10 @@ } }, "node_modules/postcss-merge-rules": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", - "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", @@ -13323,6 +14716,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13337,6 +14731,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "license": "MIT", "dependencies": { "colord": "^2.9.1", "cssnano-utils": "^3.1.0", @@ -13353,6 +14748,7 @@ "version": "5.1.4", "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "cssnano-utils": "^3.1.0", @@ -13369,6 +14765,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.5" }, @@ -13380,9 +14777,10 @@ } }, "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -13391,9 +14789,10 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -13407,9 +14806,10 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "license": "ISC", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -13424,6 +14824,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", "dependencies": { "icss-utils": "^5.0.0" }, @@ -13435,19 +14836,26 @@ } }, "node_modules/postcss-nested": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", - "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } @@ -13456,6 +14864,7 @@ "version": "10.2.0", "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", + "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -13475,6 +14884,7 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", + "license": "CC0-1.0", "dependencies": { "@csstools/normalize.css": "*", "postcss-browser-comments": "^4", @@ -13492,6 +14902,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -13503,6 +14914,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13517,6 +14929,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13531,6 +14944,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13545,6 +14959,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13559,6 +14974,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13573,6 +14989,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" @@ -13588,6 +15005,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "license": "MIT", "dependencies": { "normalize-url": "^6.0.1", "postcss-value-parser": "^4.2.0" @@ -13603,6 +15021,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13614,9 +15033,9 @@ } }, "node_modules/postcss-opacity-percentage": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz", - "integrity": "sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", "funding": [ { "type": "kofi", @@ -13627,14 +15046,19 @@ "url": "https://liberapay.com/mrcgrtz" } ], + "license": "MIT", "engines": { "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-ordered-values": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "license": "MIT", "dependencies": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" @@ -13650,6 +15074,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13668,6 +15093,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "license": "MIT", "peerDependencies": { "postcss": "^8" } @@ -13676,6 +15102,7 @@ "version": "7.0.5", "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13694,6 +15121,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", + "license": "CC0-1.0", "dependencies": { "@csstools/postcss-cascade-layers": "^1.1.1", "@csstools/postcss-color-function": "^1.1.1", @@ -13760,6 +15188,7 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", + "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -13775,9 +15204,10 @@ } }, "node_modules/postcss-reduce-initial": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", - "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" @@ -13793,6 +15223,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -13807,6 +15238,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "license": "MIT", "peerDependencies": { "postcss": "^8.0.3" } @@ -13815,6 +15247,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -13830,9 +15263,10 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", - "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -13845,6 +15279,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^2.7.0" @@ -13860,6 +15295,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", "engines": { "node": ">= 10" } @@ -13868,6 +15304,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" @@ -13879,12 +15316,14 @@ "node_modules/postcss-svgo/node_modules/mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "license": "CC0-1.0" }, "node_modules/postcss-svgo/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -13893,6 +15332,7 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "license": "MIT", "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", @@ -13913,6 +15353,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.5" }, @@ -13926,12 +15367,14 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -13940,6 +15383,7 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -13951,6 +15395,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "license": "MIT", "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" @@ -13960,6 +15405,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -13973,6 +15419,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -13980,15 +15427,23 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "license": "MIT" + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" }, "node_modules/promise": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "license": "MIT", "dependencies": { "asap": "~2.0.6" } @@ -13997,6 +15452,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -14009,21 +15465,18 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -14036,6 +15489,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -14043,12 +15497,14 @@ "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "license": "MIT" }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", "engines": { "node": ">=6" } @@ -14057,6 +15513,8 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", + "license": "MIT", "engines": { "node": ">=0.6.0", "teleport": ">=0.2.0" @@ -14066,6 +15524,7 @@ "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -14079,7 +15538,8 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -14098,23 +15558,14 @@ "type": "consulting", "url": "https://feross.org/support" } - ] - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + ], + "license": "MIT" }, "node_modules/raf": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "license": "MIT", "dependencies": { "performance-now": "^2.1.0" } @@ -14123,6 +15574,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -14131,6 +15583,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -14139,6 +15592,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -14153,6 +15607,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -14161,6 +15616,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -14169,9 +15625,10 @@ } }, "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -14183,6 +15640,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", + "license": "MIT", "dependencies": { "core-js": "^3.19.2", "object-assign": "^4.1.1", @@ -14195,10 +15653,17 @@ "node": ">=14" } }, + "node_modules/react-app-polyfill/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.16.0", "address": "^1.1.2", @@ -14229,55 +15694,15 @@ "node": ">=14" } }, - "node_modules/react-dev-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/react-dev-utils/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/react-dev-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/react-dev-utils/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { "node": ">=10" }, @@ -14285,59 +15710,90 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/react-dev-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "license": "MIT", "engines": { "node": ">= 12.13.0" } }, - "node_modules/react-dev-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/react-dev-utils/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, "node_modules/react-error-overlay": { "version": "6.0.11", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", + "license": "MIT" }, "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" }, "node_modules/react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -14346,6 +15802,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", @@ -14418,14 +15875,16 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", "dependencies": { "pify": "^2.3.0" } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -14439,6 +15898,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -14450,6 +15910,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "license": "MIT", "dependencies": { "minimatch": "^3.0.5" }, @@ -14461,6 +15922,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "license": "MIT", "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" @@ -14469,48 +15931,19 @@ "node": ">=8" } }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "license": "MIT", "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-parser": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", - "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" }, "engines": { "node": ">= 0.4" @@ -14519,25 +15952,72 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, "engines": { - "node": ">=8" + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", + "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", + "license": "MIT" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "license": "MIT", "dependencies": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" @@ -14546,15 +16026,11 @@ "node": ">=4" } }, - "node_modules/regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" - }, "node_modules/regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "license": "BSD-2-Clause", "dependencies": { "jsesc": "~0.5.0" }, @@ -14570,10 +16046,29 @@ "jsesc": "bin/jsesc" } }, + "node_modules/rehackt": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.1.0.tgz", + "integrity": "sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -14582,6 +16077,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "license": "MIT", "dependencies": { "css-select": "^4.1.3", "dom-converter": "^0.2.0", @@ -14594,6 +16090,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -14602,6 +16099,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -14609,14 +16107,16 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -14631,6 +16131,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -14642,6 +16143,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", "engines": { "node": ">=8" } @@ -14650,6 +16152,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", + "license": "MIT", "dependencies": { "adjust-sourcemap-loader": "^4.0.0", "convert-source-map": "^1.7.0", @@ -14673,15 +16176,23 @@ } } }, + "node_modules/resolve-url-loader/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, "node_modules/resolve-url-loader/node_modules/picocolors": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "license": "ISC" }, "node_modules/resolve-url-loader/node_modules/postcss": { "version": "7.0.39", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "license": "MIT", "dependencies": { "picocolors": "^0.2.1", "source-map": "^0.6.1" @@ -14698,14 +16209,16 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "license": "MIT", "engines": { "node": ">=10" } @@ -14714,6 +16227,7 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/response-iterator/-/response-iterator-0.2.6.tgz", "integrity": "sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==", + "license": "MIT", "engines": { "node": ">=0.8" } @@ -14722,6 +16236,7 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "engines": { "node": ">= 4" } @@ -14730,6 +16245,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -14739,6 +16255,8 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -14753,6 +16271,7 @@ "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "license": "MIT", "bin": { "rollup": "dist/bin/rollup" }, @@ -14768,6 +16287,7 @@ "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.10.4", "jest-worker": "^26.2.1", @@ -14778,18 +16298,11 @@ "rollup": "^2.0.0" } }, - "node_modules/rollup-plugin-terser/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/rollup-plugin-terser/node_modules/jest-worker": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -14803,21 +16316,11 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, - "node_modules/rollup-plugin-terser/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -14836,10 +16339,29 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -14857,17 +16379,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -14875,17 +16402,20 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/sanitize.css": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", - "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==", + "license": "CC0-1.0" }, "node_modules/sass-loader": { "version": "12.6.0", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "license": "MIT", "dependencies": { "klona": "^2.0.4", "neo-async": "^2.6.2" @@ -14922,12 +16452,14 @@ "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "license": "ISC" }, "node_modules/saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" }, @@ -14936,40 +16468,80 @@ } }, "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" } }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "license": "MIT" }, "node_modules/selfsigned": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", - "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "license": "MIT", "dependencies": { + "@types/node-forge": "^1.3.0", "node-forge": "^1" }, "engines": { @@ -14977,12 +16549,10 @@ } }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -14994,6 +16564,7 @@ "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -15017,6 +16588,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -15024,17 +16596,20 @@ "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -15043,6 +16618,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "license": "MIT", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -15060,6 +16636,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -15068,6 +16645,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -15076,6 +16654,7 @@ "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "license": "MIT", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -15089,22 +16668,26 @@ "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "license": "ISC" }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -15113,6 +16696,7 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -15123,15 +16707,49 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -15143,26 +16761,33 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", - "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15171,17 +16796,20 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", "engines": { "node": ">=8" } @@ -15190,6 +16818,7 @@ "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "license": "MIT", "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -15199,20 +16828,23 @@ "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "license": "MIT" }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -15221,6 +16853,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", + "license": "MIT", "dependencies": { "abab": "^2.0.5", "iconv-lite": "^0.6.3", @@ -15241,6 +16874,7 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -15250,6 +16884,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -15257,12 +16892,15 @@ "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "license": "MIT" }, "node_modules/spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "license": "MIT", "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -15278,6 +16916,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "license": "MIT", "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -15290,18 +16929,21 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", + "license": "MIT" }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -15313,6 +16955,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", "engines": { "node": ">=8" } @@ -15320,20 +16963,135 @@ "node_modules/stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "license": "MIT" + }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "license": "MIT", + "dependencies": { + "escodegen": "^1.8.1" + } + }, + "node_modules/static-eval/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/static-eval/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/static-eval/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-eval/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "license": "MIT", + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -15342,6 +17100,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -15353,12 +17112,14 @@ "node_modules/string-natural-compare": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", - "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", + "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -15368,50 +17129,123 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string.prototype.includes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", + "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } }, "node_modules/string.prototype.matchall": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", - "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.3", - "side-channel": "^1.0.4" + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15421,6 +17255,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "license": "BSD-2-Clause", "dependencies": { "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", @@ -15434,6 +17269,20 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -15445,6 +17294,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "license": "MIT", "engines": { "node": ">=8" } @@ -15453,6 +17303,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "license": "MIT", "engines": { "node": ">=10" } @@ -15461,6 +17312,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -15469,6 +17321,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "license": "MIT", "dependencies": { "min-indent": "^1.0.0" }, @@ -15480,6 +17333,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -15488,9 +17342,10 @@ } }, "node_modules/style-loader": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "license": "MIT", "engines": { "node": ">= 12.13.0" }, @@ -15506,6 +17361,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" @@ -15522,6 +17378,7 @@ "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.0.tgz", "integrity": "sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==", "deprecated": "The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md", + "license": "MIT", "dependencies": { "backo2": "^1.0.2", "eventemitter3": "^3.1.0", @@ -15533,34 +17390,107 @@ "graphql": "^15.7.2 || ^16.0.0" } }, - "node_modules/subscriptions-transport-ws/node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, "node_modules/subscriptions-transport-ws/node_modules/symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" }, "engines": { - "node": ">=4" + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/supports-hyperlinks": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -15569,29 +17499,11 @@ "node": ">=8" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -15602,13 +17514,15 @@ "node_modules/svg-parser": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "license": "MIT" }, "node_modules/svgo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "license": "MIT", "dependencies": { "chalk": "^2.4.1", "coa": "^2.0.2", @@ -15631,10 +17545,52 @@ "node": ">=4.0.0" } }, + "node_modules/svgo/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/svgo/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, "node_modules/svgo/node_modules/css-select": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^3.2.1", @@ -15646,6 +17602,7 @@ "version": "3.4.2", "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -15657,6 +17614,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "entities": "^2.0.0" @@ -15666,6 +17624,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "0", "domelementtype": "1" @@ -15674,20 +17633,53 @@ "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "license": "BSD-2-Clause" + }, + "node_modules/svgo/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/svgo/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } }, "node_modules/svgo/node_modules/nth-check": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "~1.0.0" } }, + "node_modules/svgo/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/symbol-observable": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "license": "MIT", "engines": { "node": ">=0.10" } @@ -15695,57 +17687,51 @@ "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "license": "MIT" }, "node_modules/tailwindcss": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", - "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", + "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==", + "license": "MIT", "dependencies": { + "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.5.3", - "color-name": "^1.1.4", - "detective": "^5.2.1", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.2.12", + "fast-glob": "^3.3.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "lilconfig": "^2.0.6", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.18", - "postcss-import": "^14.1.0", - "postcss-js": "^4.0.0", - "postcss-load-config": "^3.1.4", - "postcss-nested": "6.0.0", - "postcss-selector-parser": "^6.0.10", - "postcss-value-parser": "^4.2.0", - "quick-lru": "^5.1.1", - "resolve": "^1.22.1" + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" }, "engines": { - "node": ">=12.13.0" - }, - "peerDependencies": { - "postcss": "^8.0.9" + "node": ">=14.0.0" } }, - "node_modules/tailwindcss/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "license": "MIT", "engines": { "node": ">=6" } @@ -15754,6 +17740,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -15762,6 +17749,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "license": "MIT", "dependencies": { "is-stream": "^2.0.0", "temp-dir": "^2.0.0", @@ -15779,6 +17767,7 @@ "version": "0.16.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -15790,6 +17779,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" @@ -15802,9 +17792,10 @@ } }, "node_modules/terser": { - "version": "5.30.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", - "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -15822,6 +17813,7 @@ "version": "5.3.10", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -15851,15 +17843,35 @@ } } }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -15872,27 +17884,53 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } }, "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==" + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", + "license": "MIT" }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "license": "MIT" }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "license": "MIT", "engines": { "node": ">=4" } @@ -15901,6 +17939,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -15912,14 +17951,16 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -15934,6 +17975,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", "engines": { "node": ">= 4.0.0" } @@ -15942,6 +17984,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "license": "MIT", "dependencies": { "punycode": "^2.1.1" }, @@ -15952,12 +17995,20 @@ "node_modules/tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "license": "MIT" + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" }, "node_modules/ts-invariant": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" }, @@ -15966,12 +18017,13 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } @@ -15980,6 +18032,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -15991,19 +18044,22 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -16017,12 +18073,14 @@ "node_modules/tsutils/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -16034,6 +18092,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "license": "MIT", "engines": { "node": ">=4" } @@ -16042,6 +18101,7 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -16053,6 +18113,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -16061,31 +18122,107 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "license": "MIT", "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "license": "Apache-2.0", "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -16096,10 +18233,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "license": "MIT", "engines": { "node": ">=4" } @@ -16108,6 +18258,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -16120,6 +18271,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "license": "MIT", "engines": { "node": ">=4" } @@ -16128,6 +18280,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "license": "MIT", "engines": { "node": ">=4" } @@ -16136,6 +18289,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "license": "MIT", "dependencies": { "crypto-random-string": "^2.0.0" }, @@ -16144,9 +18298,10 @@ } }, "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -16155,6 +18310,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -16162,21 +18318,23 @@ "node_modules/unquote": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", + "license": "MIT" }, "node_modules/upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "license": "MIT", "engines": { "node": ">=4", "yarn": "*" } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "funding": [ { "type": "opencollective", @@ -16191,9 +18349,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -16206,6 +18365,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -16214,6 +18374,7 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -16222,12 +18383,14 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/util.promisify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "license": "MIT", "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.2", @@ -16241,12 +18404,14 @@ "node_modules/utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -16255,6 +18420,7 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -16263,6 +18429,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "license": "ISC", "dependencies": { "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0", @@ -16272,10 +18439,17 @@ "node": ">=10.12.0" } }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -16285,6 +18459,7 @@ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "license": "MIT", "dependencies": { "browser-process-hrtime": "^1.0.0" } @@ -16293,6 +18468,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "license": "MIT", "dependencies": { "xml-name-validator": "^3.0.0" }, @@ -16304,14 +18480,16 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } }, "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -16324,6 +18502,7 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } @@ -16331,31 +18510,33 @@ "node_modules/web-vitals": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", - "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" + "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==", + "license": "Apache-2.0" }, "node_modules/webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "license": "BSD-2-Clause", "engines": { "node": ">=10.4" } }, "node_modules/webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -16391,6 +18572,7 @@ "version": "5.3.4", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -16409,59 +18591,11 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/webpack-dev-server": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", - "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", + "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -16469,7 +18603,7 @@ "@types/serve-index": "^1.9.1", "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", + "@types/ws": "^8.5.5", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.0.11", "chokidar": "^3.5.3", @@ -16482,6 +18616,7 @@ "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.3", "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", "open": "^8.0.9", "p-retry": "^4.5.0", "rimraf": "^3.0.2", @@ -16490,8 +18625,8 @@ "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" @@ -16507,70 +18642,25 @@ "webpack": "^4.37.0 || ^5.0.0" }, "peerDependenciesMeta": { + "webpack": { + "optional": true + }, "webpack-cli": { "optional": true } } }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -16585,6 +18675,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", + "license": "MIT", "dependencies": { "tapable": "^2.0.0", "webpack-sources": "^2.2.0" @@ -16600,6 +18691,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -16608,6 +18700,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "license": "MIT", "dependencies": { "source-list-map": "^2.0.1", "source-map": "^0.6.1" @@ -16620,6 +18713,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -16628,6 +18722,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -16640,14 +18735,34 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -16661,6 +18776,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } @@ -16669,6 +18785,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "license": "MIT", "dependencies": { "iconv-lite": "0.4.24" } @@ -16677,6 +18794,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -16685,19 +18803,22 @@ } }, "node_modules/whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT" }, "node_modules/whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "license": "MIT" }, "node_modules/whatwg-url": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "license": "MIT", "dependencies": { "lodash": "^4.7.0", "tr46": "^2.1.0", @@ -16711,6 +18832,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -16725,6 +18847,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -16736,31 +18859,61 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "node_modules/which-builtin-type": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "license": "MIT", "dependencies": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -16773,31 +18926,35 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/workbox-background-sync": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", - "integrity": "sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "license": "MIT", "dependencies": { "idb": "^7.0.1", - "workbox-core": "6.5.4" + "workbox-core": "6.6.0" } }, "node_modules/workbox-broadcast-update": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz", - "integrity": "sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "license": "MIT", "dependencies": { - "workbox-core": "6.5.4" + "workbox-core": "6.6.0" } }, "node_modules/workbox-build": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.4.tgz", - "integrity": "sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "license": "MIT", "dependencies": { "@apideck/better-ajv-errors": "^0.3.1", "@babel/core": "^7.11.1", @@ -16821,21 +18978,21 @@ "strip-comments": "^2.0.1", "tempy": "^0.6.0", "upath": "^1.2.0", - "workbox-background-sync": "6.5.4", - "workbox-broadcast-update": "6.5.4", - "workbox-cacheable-response": "6.5.4", - "workbox-core": "6.5.4", - "workbox-expiration": "6.5.4", - "workbox-google-analytics": "6.5.4", - "workbox-navigation-preload": "6.5.4", - "workbox-precaching": "6.5.4", - "workbox-range-requests": "6.5.4", - "workbox-recipes": "6.5.4", - "workbox-routing": "6.5.4", - "workbox-strategies": "6.5.4", - "workbox-streams": "6.5.4", - "workbox-sw": "6.5.4", - "workbox-window": "6.5.4" + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" }, "engines": { "node": ">=10.0.0" @@ -16845,6 +19002,7 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "license": "MIT", "dependencies": { "json-schema": "^0.4.0", "jsonpointer": "^5.0.0", @@ -16858,14 +19016,15 @@ } }, "node_modules/workbox-build/node_modules/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -16876,6 +19035,7 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -16889,12 +19049,14 @@ "node_modules/workbox-build/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/workbox-build/node_modules/source-map": { "version": "0.8.0-beta.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "license": "BSD-3-Clause", "dependencies": { "whatwg-url": "^7.0.0" }, @@ -16906,6 +19068,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "license": "MIT", "dependencies": { "punycode": "^2.1.0" } @@ -16913,12 +19076,14 @@ "node_modules/workbox-build/node_modules/webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "license": "BSD-2-Clause" }, "node_modules/workbox-build/node_modules/whatwg-url": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "license": "MIT", "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -16926,117 +19091,132 @@ } }, "node_modules/workbox-cacheable-response": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz", - "integrity": "sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", + "license": "MIT", "dependencies": { - "workbox-core": "6.5.4" + "workbox-core": "6.6.0" } }, "node_modules/workbox-core": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", - "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==", + "license": "MIT" }, "node_modules/workbox-expiration": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.4.tgz", - "integrity": "sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "license": "MIT", "dependencies": { "idb": "^7.0.1", - "workbox-core": "6.5.4" + "workbox-core": "6.6.0" } }, "node_modules/workbox-google-analytics": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz", - "integrity": "sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "license": "MIT", "dependencies": { - "workbox-background-sync": "6.5.4", - "workbox-core": "6.5.4", - "workbox-routing": "6.5.4", - "workbox-strategies": "6.5.4" + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" } }, "node_modules/workbox-navigation-preload": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz", - "integrity": "sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "license": "MIT", "dependencies": { - "workbox-core": "6.5.4" + "workbox-core": "6.6.0" } }, "node_modules/workbox-precaching": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.4.tgz", - "integrity": "sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "license": "MIT", "dependencies": { - "workbox-core": "6.5.4", - "workbox-routing": "6.5.4", - "workbox-strategies": "6.5.4" + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" } }, "node_modules/workbox-range-requests": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz", - "integrity": "sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "license": "MIT", "dependencies": { - "workbox-core": "6.5.4" + "workbox-core": "6.6.0" } }, "node_modules/workbox-recipes": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.4.tgz", - "integrity": "sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "license": "MIT", "dependencies": { - "workbox-cacheable-response": "6.5.4", - "workbox-core": "6.5.4", - "workbox-expiration": "6.5.4", - "workbox-precaching": "6.5.4", - "workbox-routing": "6.5.4", - "workbox-strategies": "6.5.4" + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" } }, "node_modules/workbox-routing": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz", - "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "license": "MIT", "dependencies": { - "workbox-core": "6.5.4" + "workbox-core": "6.6.0" } }, "node_modules/workbox-strategies": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz", - "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "license": "MIT", "dependencies": { - "workbox-core": "6.5.4" + "workbox-core": "6.6.0" } }, "node_modules/workbox-streams": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.4.tgz", - "integrity": "sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "license": "MIT", "dependencies": { - "workbox-core": "6.5.4", - "workbox-routing": "6.5.4" + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" } }, "node_modules/workbox-sw": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz", - "integrity": "sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==" + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==", + "license": "MIT" }, "node_modules/workbox-webpack-plugin": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz", - "integrity": "sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "license": "MIT", "dependencies": { "fast-json-stable-stringify": "^2.1.0", "pretty-bytes": "^5.4.1", "upath": "^1.2.0", "webpack-sources": "^1.4.3", - "workbox-build": "6.5.4" + "workbox-build": "6.6.0" }, "engines": { "node": ">=10.0.0" @@ -17049,6 +19229,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -17057,24 +19238,27 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "license": "MIT", "dependencies": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" } }, "node_modules/workbox-window": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz", - "integrity": "sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", + "license": "MIT", "dependencies": { "@types/trusted-types": "^2.0.2", - "workbox-core": "6.5.4" + "workbox-core": "6.6.0" } }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -17087,45 +19271,35 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -17134,9 +19308,10 @@ } }, "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -17156,38 +19331,35 @@ "node_modules/xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "license": "Apache-2.0" }, "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", "engines": { "node": ">= 6" } @@ -17196,6 +19368,7 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -17213,6 +19386,7 @@ "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", "engines": { "node": ">=10" } @@ -17221,6 +19395,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -17231,12259 +19406,17 @@ "node_modules/zen-observable": { "version": "0.8.15", "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" + "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", + "license": "MIT" }, "node_modules/zen-observable-ts": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz", "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==", + "license": "MIT", "dependencies": { "zen-observable": "0.8.15" } } - }, - "dependencies": { - "@adobe/css-tools": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", - "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==" - }, - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@apollo/client": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.7.1.tgz", - "integrity": "sha512-xu5M/l7p9gT9Fx7nF3AQivp0XukjB7TM7tOd5wifIpI8RskYveL4I+rpTijzWrnqCPZabkbzJKH7WEAKdctt9w==", - "requires": { - "@graphql-typed-document-node/core": "^3.1.1", - "@wry/context": "^0.7.0", - "@wry/equality": "^0.5.0", - "@wry/trie": "^0.3.0", - "graphql-tag": "^2.12.6", - "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.16.1", - "prop-types": "^15.7.2", - "response-iterator": "^0.2.6", - "symbol-observable": "^4.0.0", - "ts-invariant": "^0.10.3", - "tslib": "^2.3.0", - "zen-observable-ts": "^1.2.5" - } - }, - "@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", - "requires": { - "@babel/highlight": "^7.24.2", - "picocolors": "^1.0.0" - } - }, - "@babel/compat-data": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==" - }, - "@babel/core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", - "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.5", - "@babel/parser": "^7.20.5", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/eslint-parser": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", - "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", - "requires": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", - "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", - "requires": { - "@babel/types": "^7.24.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "requires": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "requires": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", - "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", - "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.2.1" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "requires": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "requires": { - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "requires": { - "@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.1", - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "requires": { - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "requires": { - "@babel/types": "^7.20.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==" - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" - }, - "@babel/helper-wrap-function": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", - "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", - "requires": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" - } - }, - "@babel/helpers": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", - "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" - } - }, - "@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - } - }, - "@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==" - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-decorators": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.5.tgz", - "integrity": "sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/plugin-syntax-decorators": "^7.19.0" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", - "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-decorators": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", - "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", - "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz", - "integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==", - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", - "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", - "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-flow": "^7.18.6" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "requires": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", - "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", - "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", - "requires": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", - "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz", - "integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-react-constant-elements": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.20.2.tgz", - "integrity": "sha512-KS/G8YI8uwMGKErLFOHS/ekhqdHhpEloxs43NecQHVgo2QuQSyJhGIY1fL8UGl9wy5ItVwwoUL4YxVqsplGq2g==", - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", - "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.19.0" - } - }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", - "requires": { - "@babel/plugin-transform-react-jsx": "^7.18.6" - } - }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", - "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.20.2", - "regenerator-transform": "^0.15.1" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", - "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", - "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", - "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.20.2", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-typescript": "^7.20.0" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/preset-react": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", - "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.18.6", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" - } - }, - "@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" - } - }, - "@babel/runtime": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", - "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", - "requires": { - "regenerator-runtime": "^0.13.11" - } - }, - "@babel/runtime-corejs3": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz", - "integrity": "sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==", - "requires": { - "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.11" - } - }, - "@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" - } - }, - "@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", - "requires": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", - "debug": "^4.3.1", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", - "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" - }, - "@csstools/normalize.css": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", - "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==" - }, - "@csstools/postcss-cascade-layers": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", - "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", - "requires": { - "@csstools/selector-specificity": "^2.0.2", - "postcss-selector-parser": "^6.0.10" - } - }, - "@csstools/postcss-color-function": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", - "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-font-format-keywords": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", - "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-hwb-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", - "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-ic-unit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", - "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-is-pseudo-class": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", - "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", - "requires": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - } - }, - "@csstools/postcss-nested-calc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", - "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-normalize-display-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", - "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-oklab-function": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", - "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-progressive-custom-properties": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", - "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-stepped-value-functions": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", - "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-text-decoration-shorthand": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", - "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-trigonometric-functions": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", - "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-unset-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", - "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", - "requires": {} - }, - "@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", - "requires": {} - }, - "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", - "requires": { - "type-fest": "^0.20.2" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" - } - } - }, - "@graphql-typed-document-node/core": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz", - "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==", - "requires": {} - }, - "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" - }, - "@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "requires": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "requires": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - } - }, - "@jest/expect-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz", - "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==", - "requires": { - "jest-get-type": "^29.2.0" - }, - "dependencies": { - "jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==" - } - } - }, - "@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "requires": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - } - }, - "@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", - "requires": { - "@sinclair/typebox": "^0.24.1" - } - }, - "@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "requires": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "requires": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - } - }, - "@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" - }, - "@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" - }, - "@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - } - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" - }, - "@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "requires": { - "eslint-scope": "5.1.1" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - } - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", - "integrity": "sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==", - "requires": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.23.3", - "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.4", - "schema-utils": "^3.0.0", - "source-map": "^0.7.3" - } - }, - "@rollup/plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", - "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@rollup/pluginutils": "^3.1.0" - } - }, - "@rollup/plugin-node-resolve": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", - "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", - "requires": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - } - }, - "@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", - "requires": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" - } - }, - "@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "dependencies": { - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" - } - } - }, - "@rushstack/eslint-patch": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", - "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" - }, - "@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" - }, - "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@surma/rollup-plugin-off-main-thread": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", - "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", - "requires": { - "ejs": "^3.1.6", - "json5": "^2.2.0", - "magic-string": "^0.25.0", - "string.prototype.matchall": "^4.0.6" - } - }, - "@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==" - }, - "@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==" - }, - "@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", - "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==" - }, - "@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", - "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==" - }, - "@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", - "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==" - }, - "@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", - "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==" - }, - "@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", - "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==" - }, - "@svgr/babel-plugin-transform-svg-component": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", - "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==" - }, - "@svgr/babel-preset": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", - "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", - "requires": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.5.0" - } - }, - "@svgr/core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", - "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", - "requires": { - "@svgr/plugin-jsx": "^5.5.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.0" - } - }, - "@svgr/hast-util-to-babel-ast": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", - "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", - "requires": { - "@babel/types": "^7.12.6" - } - }, - "@svgr/plugin-jsx": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", - "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", - "requires": { - "@babel/core": "^7.12.3", - "@svgr/babel-preset": "^5.5.0", - "@svgr/hast-util-to-babel-ast": "^5.5.0", - "svg-parser": "^2.0.2" - } - }, - "@svgr/plugin-svgo": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", - "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", - "requires": { - "cosmiconfig": "^7.0.0", - "deepmerge": "^4.2.2", - "svgo": "^1.2.2" - } - }, - "@svgr/webpack": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", - "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", - "requires": { - "@babel/core": "^7.12.3", - "@babel/plugin-transform-react-constant-elements": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-react": "^7.12.5", - "@svgr/core": "^5.5.0", - "@svgr/plugin-jsx": "^5.5.0", - "@svgr/plugin-svgo": "^5.5.0", - "loader-utils": "^2.0.0" - } - }, - "@testing-library/dom": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", - "integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", - "pretty-format": "^27.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "requires": { - "deep-equal": "^2.0.5" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@testing-library/jest-dom": { - "version": "5.16.5", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", - "integrity": "sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==", - "requires": { - "@adobe/css-tools": "^4.0.1", - "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", - "aria-query": "^5.0.0", - "chalk": "^3.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", - "lodash": "^4.17.15", - "redent": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "requires": { - "deep-equal": "^2.0.5" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@testing-library/react": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", - "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", - "requires": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.5.0", - "@types/react-dom": "^18.0.0" - } - }, - "@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", - "requires": { - "@babel/runtime": "^7.12.5" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" - }, - "@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" - }, - "@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==" - }, - "@types/babel__core": { - "version": "7.1.20", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", - "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", - "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "@types/eslint": { - "version": "8.4.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", - "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" - }, - "@types/express": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", - "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.31", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", - "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "requires": { - "@types/node": "*" - } - }, - "@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "@types/http-proxy": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", - "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "29.2.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.3.tgz", - "integrity": "sha512-6XwoEbmatfyoCjWRX7z0fKMmgYKe9+/HrviJ5k0X/tjJWHGAezZOfYaxqQKuzG/TvQyr+ktjm4jgbk0s4/oF2w==", - "requires": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - }, - "dependencies": { - "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", - "requires": { - "@sinclair/typebox": "^0.24.1" - } - }, - "@jest/types": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", - "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", - "requires": { - "@jest/schemas": "^29.0.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.15", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz", - "integrity": "sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==", - "requires": { - "@types/yargs-parser": "*" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "diff-sequences": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", - "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==" - }, - "expect": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", - "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==", - "requires": { - "@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" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "jest-diff": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz", - "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==", - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" - } - }, - "jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==" - }, - "jest-matcher-utils": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz", - "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==", - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.3.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.3.1" - } - }, - "jest-message-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", - "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.3.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.3.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-util": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", - "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", - "requires": { - "@jest/types": "^29.3.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "pretty-format": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", - "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", - "requires": { - "@jest/schemas": "^29.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" - }, - "@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" - }, - "@types/node": { - "version": "18.11.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz", - "integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==" - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" - }, - "@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" - }, - "@types/q": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", - "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "@types/react": { - "version": "18.0.25", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.25.tgz", - "integrity": "sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-dom": { - "version": "18.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", - "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", - "requires": { - "@types/react": "*" - } - }, - "@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "requires": { - "@types/node": "*" - } - }, - "@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" - }, - "@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" - }, - "@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", - "requires": { - "@types/express": "*" - } - }, - "@types/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", - "requires": { - "@types/mime": "*", - "@types/node": "*" - } - }, - "@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", - "requires": { - "@types/node": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" - }, - "@types/testing-library__jest-dom": { - "version": "5.14.5", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz", - "integrity": "sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==", - "requires": { - "@types/jest": "*" - } - }, - "@types/trusted-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", - "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" - }, - "@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", - "requires": { - "@types/node": "*" - } - }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz", - "integrity": "sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==", - "requires": { - "@typescript-eslint/scope-manager": "5.45.0", - "@typescript-eslint/type-utils": "5.45.0", - "@typescript-eslint/utils": "5.45.0", - "debug": "^4.3.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.45.0.tgz", - "integrity": "sha512-DnRQg5+3uHHt/gaifTjwg9OKbg9/TWehfJzYHQIDJboPEbF897BKDE/qoqMhW7nf0jWRV1mwVXTaUvtB1/9Gwg==", - "requires": { - "@typescript-eslint/utils": "5.45.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.0.tgz", - "integrity": "sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==", - "requires": { - "@typescript-eslint/scope-manager": "5.45.0", - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/typescript-estree": "5.45.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz", - "integrity": "sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==", - "requires": { - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/visitor-keys": "5.45.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz", - "integrity": "sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q==", - "requires": { - "@typescript-eslint/typescript-estree": "5.45.0", - "@typescript-eslint/utils": "5.45.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.0.tgz", - "integrity": "sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==" - }, - "@typescript-eslint/typescript-estree": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz", - "integrity": "sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==", - "requires": { - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/visitor-keys": "5.45.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.45.0.tgz", - "integrity": "sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA==", - "requires": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.45.0", - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/typescript-estree": "5.45.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - } - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz", - "integrity": "sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==", - "requires": { - "@typescript-eslint/types": "5.45.0", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "@wry/context": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.0.tgz", - "integrity": "sha512-LcDAiYWRtwAoSOArfk7cuYvFXytxfVrdX7yxoUmK7pPITLk5jYh2F8knCwS7LjgYL8u1eidPlKKV6Ikqq0ODqQ==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@wry/equality": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.3.tgz", - "integrity": "sha512-avR+UXdSrsF2v8vIqIgmeTY0UR91UT+IyablCyKe/uk22uOJ8fusKZnH9JH9e1/EtLeNJBtagNmL3eJdnOV53g==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@wry/trie": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.3.2.tgz", - "integrity": "sha512-yRTyhWSls2OY/pYLfwff867r8ekooZ4UI+/gxot5Wj8EFwSf2rG+n+Mo/6LoLQm1TKA4GRj2+LCpbfS937dClQ==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==" - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" - } - } - }, - "acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "requires": {} - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} - }, - "acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "requires": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" - } - } - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" - }, - "address": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", - "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==" - }, - "adjust-sourcemap-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", - "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "requires": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - } - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "requires": { - "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - } - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "requires": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - } - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" - }, - "array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - } - }, - "array.prototype.tosorted": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", - "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.1.3" - } - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", - "requires": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" - }, - "axe-core": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", - "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==" - }, - "axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" - }, - "babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "requires": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", - "requires": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "dependencies": { - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "requires": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - } - }, - "babel-plugin-named-asset-import": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", - "requires": {} - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "requires": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - } - }, - "babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", - "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "requires": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "babel-preset-react-app": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", - "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", - "requires": { - "@babel/core": "^7.16.0", - "@babel/plugin-proposal-class-properties": "^7.16.0", - "@babel/plugin-proposal-decorators": "^7.16.4", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", - "@babel/plugin-proposal-numeric-separator": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-private-methods": "^7.16.0", - "@babel/plugin-transform-flow-strip-types": "^7.16.0", - "@babel/plugin-transform-react-display-name": "^7.16.0", - "@babel/plugin-transform-runtime": "^7.16.4", - "@babel/preset-env": "^7.16.4", - "@babel/preset-react": "^7.16.0", - "@babel/preset-typescript": "^7.16.0", - "@babel/runtime": "^7.16.3", - "babel-plugin-macros": "^3.1.0", - "babel-plugin-transform-react-remove-prop-types": "^0.4.24" - } - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "bfj": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", - "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", - "requires": { - "bluebird": "^3.5.5", - "check-types": "^11.1.1", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "bonjour-service": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.14.tgz", - "integrity": "sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==", - "requires": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" - }, - "browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "requires": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==" - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" - }, - "camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001605", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz", - "integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==" - }, - "case-sensitive-paths-webpack-plugin": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", - "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==" - }, - "check-types": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz", - "integrity": "sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA==" - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "ci-info": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", - "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==" - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" - }, - "clean-css": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", - "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==" - }, - "coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - } - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, - "colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" - }, - "common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, - "common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" - }, - "connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==" - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "core-js": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", - "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==" - }, - "core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", - "requires": { - "browserslist": "^4.21.4" - } - }, - "core-js-pure": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", - "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==" - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" - }, - "css-blank-pseudo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", - "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", - "requires": { - "postcss-selector-parser": "^6.0.9" - } - }, - "css-declaration-sorter": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", - "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", - "requires": {} - }, - "css-has-pseudo": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", - "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", - "requires": { - "postcss-selector-parser": "^6.0.9" - } - }, - "css-loader": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.2.tgz", - "integrity": "sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==", - "requires": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.18", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" - } - }, - "css-minimizer-webpack-plugin": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", - "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", - "requires": { - "cssnano": "^5.0.6", - "jest-worker": "^27.0.2", - "postcss": "^8.3.5", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-prefers-color-scheme": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", - "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", - "requires": {} - }, - "css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" - }, - "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" - }, - "css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" - }, - "cssdb": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.2.0.tgz", - "integrity": "sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg==" - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" - }, - "cssnano": { - "version": "5.1.14", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", - "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", - "requires": { - "cssnano-preset-default": "^5.2.13", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - } - }, - "cssnano-preset-default": { - "version": "5.2.13", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", - "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", - "requires": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.3", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.1", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - } - }, - "cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "requires": {} - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "requires": { - "css-tree": "^1.1.2" - }, - "dependencies": { - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - } - } - }, - "csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" - }, - "damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decimal.js": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", - "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==" - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" - }, - "deep-equal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.1.0.tgz", - "integrity": "sha512-2pxgvWu3Alv1PoWEyVg7HS8YhGlUFUV7N5oOvfL6d+7xAmLSemMwv/c8Zv/i9KFzxV5Kt5CAvQc70fLwVuf4UA==", - "requires": { - "call-bind": "^1.0.2", - "es-get-iterator": "^1.1.2", - "get-intrinsic": "^1.1.3", - "is-arguments": "^1.1.1", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.8" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - } - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" - }, - "default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "requires": { - "execa": "^5.0.0" - } - }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "defined": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", - "requires": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - } - }, - "didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==" - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" - }, - "dns-packet": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", - "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", - "requires": { - "@leichtgewicht/ip-codec": "^2.0.1" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-accessibility-api": { - "version": "0.5.14", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", - "integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==" - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" - } - } - }, - "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" - }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "requires": { - "jake": "^10.8.5" - } - }, - "electron-to-chromium": { - "version": "1.4.724", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.724.tgz", - "integrity": "sha512-RTRvkmRkGhNBPPpdrgtDKvmOEYTrPlXDfc0J/Nfq5s29tEahAwhiX4mmhNzj6febWMleulxVYPh7QwCSL/EldA==" - }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==" - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, - "enhanced-resolve": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", - "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "requires": { - "stackframe": "^1.3.4" - } - }, - "es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" - }, - "es-get-iterator": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", - "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.0", - "has-symbols": "^1.0.1", - "is-arguments": "^1.1.0", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - } - } - }, - "es-module-lexer": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz", - "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==" - }, - "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "requires": { - "has": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" - }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", - "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", - "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.15.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - }, - "globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" - } - } - }, - "eslint-config-react-app": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", - "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", - "requires": { - "@babel/core": "^7.16.0", - "@babel/eslint-parser": "^7.16.3", - "@rushstack/eslint-patch": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", - "babel-preset-react-app": "^10.0.1", - "confusing-browser-globals": "^1.0.11", - "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jest": "^25.3.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.27.1", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-testing-library": "^5.0.1" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", - "requires": { - "debug": "^3.2.7" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-flowtype": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", - "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", - "requires": { - "lodash": "^4.17.21", - "string-natural-compare": "^3.0.1" - } - }, - "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "eslint-plugin-jest": { - "version": "25.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", - "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", - "requires": { - "@typescript-eslint/experimental-utils": "^5.0.0" - } - }, - "eslint-plugin-jsx-a11y": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", - "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", - "requires": { - "@babel/runtime": "^7.18.9", - "aria-query": "^4.2.2", - "array-includes": "^3.1.5", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.4.3", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.3.2", - "language-tags": "^1.0.5", - "minimatch": "^3.1.2", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "eslint-plugin-react": { - "version": "7.31.11", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", - "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", - "requires": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.8" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "requires": { - "esutils": "^2.0.2" - } - }, - "resolve": { - "version": "2.0.0-next.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", - "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "requires": {} - }, - "eslint-plugin-testing-library": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.9.1.tgz", - "integrity": "sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ==", - "requires": { - "@typescript-eslint/utils": "^5.13.0" - } - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" - } - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" - }, - "eslint-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", - "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", - "requires": { - "@types/eslint": "^7.29.0 || ^8.4.1", - "jest-worker": "^28.0.2", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "jest-worker": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", - "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" - }, - "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==" - }, - "expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "requires": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - } - }, - "express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-patch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - } - }, - "filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "requires": { - "minimatch": "^5.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.1.tgz", - "integrity": "sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==", - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" - }, - "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, - "fork-ts-checker-webpack-plugin": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz", - "integrity": "sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - } - } - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "requires": { - "is-glob": "^4.0.3" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" - }, - "graphql": { - "version": "16.8.1", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", - "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==" - }, - "graphql-tag": { - "version": "2.12.6", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", - "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", - "requires": { - "tslib": "^2.1.0" - } - }, - "graphql-ws": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.11.2.tgz", - "integrity": "sha512-4EiZ3/UXYcjm+xFGP544/yW1+DVI8ZpKASFbzrV5EDTFWJp0ZvLl4Dy2fSZAzz9imKp5pZMIcjB0x/H69Pv/6w==", - "requires": {} - }, - "gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "requires": { - "duplexer": "^0.1.2" - } - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "harmony-reflect": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==" - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "requires": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - } - }, - "html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", - "requires": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - } - }, - "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "requires": {} - }, - "idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" - }, - "identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", - "requires": { - "harmony-reflect": "^1.4.6" - } - }, - "ignore": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", - "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==" - }, - "immer": { - "version": "9.0.16", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz", - "integrity": "sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ==" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - } - } - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==" - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==" - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" - }, - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" - }, - "is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" - }, - "is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==" - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==" - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==" - }, - "istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" - }, - "jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", - "requires": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "requires": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - } - }, - "jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "requires": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "requires": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "requires": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==" - }, - "jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "requires": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "requires": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "requires": {} - }, - "jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==" - }, - "jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "requires": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - } - }, - "jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "requires": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - } - }, - "jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "requires": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-watch-typeahead": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", - "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", - "requires": { - "ansi-escapes": "^4.3.1", - "chalk": "^4.0.0", - "jest-regex-util": "^28.0.0", - "jest-watcher": "^28.0.0", - "slash": "^4.0.0", - "string-length": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "@jest/console": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", - "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "slash": "^3.0.0" - }, - "dependencies": { - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - } - } - }, - "@jest/test-result": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", - "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", - "requires": { - "@jest/console": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "requires": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.15", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz", - "integrity": "sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==", - "requires": { - "@types/yargs-parser": "*" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - } - } - }, - "jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==" - }, - "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-watcher": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", - "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", - "requires": { - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.3", - "string-length": "^4.0.1" - }, - "dependencies": { - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - }, - "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" - }, - "string-length": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", - "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", - "requires": { - "char-regex": "^2.0.0", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "char-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", - "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==" - } - } - }, - "strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "requires": { - "ansi-regex": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" - } - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "requires": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" - }, - "jsx-ast-utils": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", - "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", - "requires": { - "array-includes": "^3.1.5", - "object.assign": "^4.1.3" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" - }, - "klona": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", - "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==" - }, - "language-subtag-registry": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", - "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" - }, - "language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", - "requires": { - "language-subtag-registry": "~0.3.2" - } - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lilconfig": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==" - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" - }, - "loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "requires": { - "tslib": "^2.0.3" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==" - }, - "magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "requires": { - "sourcemap-codec": "^1.4.8" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "requires": { - "tmpl": "1.0.5" - } - }, - "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "memfs": { - "version": "3.4.12", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.12.tgz", - "integrity": "sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==", - "requires": { - "fs-monkey": "^1.0.3" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" - }, - "mini-css-extract-plugin": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.1.tgz", - "integrity": "sha512-viOoaUFy+Z2w43VsGPbtfwFrr0tKwDctK9dUofG5MBViYhD1noGFUzzDIVw0KPwCGUP+c7zqLxm+acuQs7zLzw==", - "requires": { - "schema-utils": "^4.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - } - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "requires": { - "minimist": "^1.2.6" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "requires": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - } - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" - }, - "natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" - }, - "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "requires": { - "boolbase": "^1.0.0" - } - }, - "nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" - }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", - "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", - "requires": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "object.hasown": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", - "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", - "requires": { - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "optimism": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.16.2.tgz", - "integrity": "sha512-zWNbgWj+3vLEjZNIh/okkY2EUfX+vB9TJopzIZwT1xxaMqC5hRLLraePod4c5n4He08xuXNH+zhKFFCu390wiQ==", - "requires": { - "@wry/context": "^0.7.0", - "@wry/trie": "^0.3.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "requires": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" - }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==" - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" - } - } - }, - "postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "postcss-attribute-case-insensitive": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", - "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-browser-comments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", - "requires": {} - }, - "postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "requires": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-clamp": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", - "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-color-functional-notation": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", - "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-color-hex-alpha": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", - "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-color-rebeccapurple": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", - "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-colormin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", - "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", - "requires": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "requires": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-custom-media": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", - "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-custom-properties": { - "version": "12.1.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", - "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-custom-selectors": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", - "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-dir-pseudo-class": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", - "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "requires": {} - }, - "postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "requires": {} - }, - "postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "requires": {} - }, - "postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "requires": {} - }, - "postcss-double-position-gradients": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", - "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-env-function": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", - "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-flexbugs-fixes": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", - "requires": {} - }, - "postcss-focus-visible": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", - "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", - "requires": { - "postcss-selector-parser": "^6.0.9" - } - }, - "postcss-focus-within": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", - "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", - "requires": { - "postcss-selector-parser": "^6.0.9" - } - }, - "postcss-font-variant": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", - "requires": {} - }, - "postcss-gap-properties": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", - "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", - "requires": {} - }, - "postcss-image-set-function": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", - "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-import": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", - "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", - "requires": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - } - }, - "postcss-initial": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", - "requires": {} - }, - "postcss-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", - "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", - "requires": { - "camelcase-css": "^2.0.1" - } - }, - "postcss-lab-function": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", - "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-load-config": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", - "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", - "requires": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" - } - }, - "postcss-loader": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", - "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", - "requires": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.5", - "semver": "^7.3.5" - } - }, - "postcss-logical": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", - "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", - "requires": {} - }, - "postcss-media-minmax": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", - "requires": {} - }, - "postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "requires": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - } - }, - "postcss-merge-rules": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", - "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "requires": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "requires": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "requires": {} - }, - "postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-nested": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", - "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-nesting": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", - "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", - "requires": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-normalize": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", - "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", - "requires": { - "@csstools/normalize.css": "*", - "postcss-browser-comments": "^4", - "sanitize.css": "*" - } - }, - "postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "requires": {} - }, - "postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "requires": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "requires": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-opacity-percentage": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz", - "integrity": "sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==" - }, - "postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "requires": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-overflow-shorthand": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", - "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-page-break": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "requires": {} - }, - "postcss-place": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", - "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-preset-env": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", - "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", - "requires": { - "@csstools/postcss-cascade-layers": "^1.1.1", - "@csstools/postcss-color-function": "^1.1.1", - "@csstools/postcss-font-format-keywords": "^1.0.1", - "@csstools/postcss-hwb-function": "^1.0.2", - "@csstools/postcss-ic-unit": "^1.0.1", - "@csstools/postcss-is-pseudo-class": "^2.0.7", - "@csstools/postcss-nested-calc": "^1.0.0", - "@csstools/postcss-normalize-display-values": "^1.0.1", - "@csstools/postcss-oklab-function": "^1.1.1", - "@csstools/postcss-progressive-custom-properties": "^1.3.0", - "@csstools/postcss-stepped-value-functions": "^1.0.1", - "@csstools/postcss-text-decoration-shorthand": "^1.0.0", - "@csstools/postcss-trigonometric-functions": "^1.0.2", - "@csstools/postcss-unset-value": "^1.0.2", - "autoprefixer": "^10.4.13", - "browserslist": "^4.21.4", - "css-blank-pseudo": "^3.0.3", - "css-has-pseudo": "^3.0.4", - "css-prefers-color-scheme": "^6.0.3", - "cssdb": "^7.1.0", - "postcss-attribute-case-insensitive": "^5.0.2", - "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^4.2.4", - "postcss-color-hex-alpha": "^8.0.4", - "postcss-color-rebeccapurple": "^7.1.1", - "postcss-custom-media": "^8.0.2", - "postcss-custom-properties": "^12.1.10", - "postcss-custom-selectors": "^6.0.3", - "postcss-dir-pseudo-class": "^6.0.5", - "postcss-double-position-gradients": "^3.1.2", - "postcss-env-function": "^4.0.6", - "postcss-focus-visible": "^6.0.4", - "postcss-focus-within": "^5.0.4", - "postcss-font-variant": "^5.0.0", - "postcss-gap-properties": "^3.0.5", - "postcss-image-set-function": "^4.0.7", - "postcss-initial": "^4.0.1", - "postcss-lab-function": "^4.2.1", - "postcss-logical": "^5.0.4", - "postcss-media-minmax": "^5.0.0", - "postcss-nesting": "^10.2.0", - "postcss-opacity-percentage": "^1.1.2", - "postcss-overflow-shorthand": "^3.0.4", - "postcss-page-break": "^3.0.4", - "postcss-place": "^7.0.5", - "postcss-pseudo-class-any-link": "^7.1.6", - "postcss-replace-overflow-wrap": "^4.0.0", - "postcss-selector-not": "^6.0.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-pseudo-class-any-link": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", - "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-reduce-initial": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", - "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", - "requires": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-replace-overflow-wrap": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", - "requires": {} - }, - "postcss-selector-not": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", - "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-selector-parser": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", - "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "requires": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - } - } - } - }, - "postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" - }, - "pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" - }, - "pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "requires": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" - } - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "requires": { - "asap": "~2.0.6" - } - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "dependencies": { - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - } - } - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" - }, - "raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "requires": { - "performance-now": "^2.1.0" - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-app-polyfill": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", - "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", - "requires": { - "core-js": "^3.19.2", - "object-assign": "^4.1.1", - "promise": "^8.1.0", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.9", - "whatwg-fetch": "^3.6.2" - } - }, - "react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "requires": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - } - }, - "react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "react-refresh": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", - "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" - }, - "react-scripts": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", - "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", - "requires": { - "@babel/core": "^7.16.0", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", - "@svgr/webpack": "^5.5.0", - "babel-jest": "^27.4.2", - "babel-loader": "^8.2.3", - "babel-plugin-named-asset-import": "^0.3.8", - "babel-preset-react-app": "^10.0.1", - "bfj": "^7.0.2", - "browserslist": "^4.18.1", - "camelcase": "^6.2.1", - "case-sensitive-paths-webpack-plugin": "^2.4.0", - "css-loader": "^6.5.1", - "css-minimizer-webpack-plugin": "^3.2.0", - "dotenv": "^10.0.0", - "dotenv-expand": "^5.1.0", - "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.1", - "eslint-webpack-plugin": "^3.1.1", - "file-loader": "^6.2.0", - "fs-extra": "^10.0.0", - "fsevents": "^2.3.2", - "html-webpack-plugin": "^5.5.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^27.4.3", - "jest-resolve": "^27.4.2", - "jest-watch-typeahead": "^1.0.0", - "mini-css-extract-plugin": "^2.4.5", - "postcss": "^8.4.4", - "postcss-flexbugs-fixes": "^5.0.2", - "postcss-loader": "^6.2.1", - "postcss-normalize": "^10.0.1", - "postcss-preset-env": "^7.0.1", - "prompts": "^2.4.2", - "react-app-polyfill": "^3.0.0", - "react-dev-utils": "^12.0.1", - "react-refresh": "^0.11.0", - "resolve": "^1.20.0", - "resolve-url-loader": "^4.0.0", - "sass-loader": "^12.3.0", - "semver": "^7.3.5", - "source-map-loader": "^3.0.0", - "style-loader": "^3.3.1", - "tailwindcss": "^3.0.2", - "terser-webpack-plugin": "^5.2.5", - "webpack": "^5.64.4", - "webpack-dev-server": "^4.6.0", - "webpack-manifest-plugin": "^4.0.2", - "workbox-webpack-plugin": "^6.4.1" - } - }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "requires": { - "pify": "^2.3.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "requires": { - "minimatch": "^3.0.5" - } - }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regex-parser": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", - "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" - }, - "regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - } - }, - "regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" - }, - "regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" - }, - "renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "requires": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - }, - "resolve-url-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", - "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", - "requires": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^7.0.35", - "source-map": "0.6.1" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==" - }, - "response-iterator": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/response-iterator/-/response-iterator-0.2.6.tgz", - "integrity": "sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==" - }, - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", - "requires": { - "fsevents": "~2.3.2" - } - }, - "rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", - "requires": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sanitize.css": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", - "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" - }, - "sass-loader": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", - "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", - "requires": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "requires": { - "xmlchars": "^2.2.0" - } - }, - "scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "selfsigned": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", - "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", - "requires": { - "node-forge": "^1" - } - }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" - } - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shell-quote": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", - "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==" - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" - }, - "source-map-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", - "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", - "requires": { - "abab": "^2.0.5", - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.1" - } - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" - }, - "stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" - } - } - }, - "stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-natural-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", - "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - } - } - }, - "string.prototype.matchall": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", - "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.3", - "side-channel": "^1.0.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" - }, - "strip-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", - "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "requires": { - "min-indent": "^1.0.0" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" - }, - "style-loader": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", - "requires": {} - }, - "stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "requires": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - } - }, - "subscriptions-transport-ws": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.0.tgz", - "integrity": "sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==", - "requires": { - "backo2": "^1.0.2", - "eventemitter3": "^3.1.0", - "iterall": "^1.2.1", - "symbol-observable": "^1.0.4", - "ws": "^5.2.0 || ^6.0.0 || ^7.0.0" - }, - "dependencies": { - "eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "dependencies": { - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==" - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - }, - "dependencies": { - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - } - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "requires": { - "boolbase": "~1.0.0" - } - } - } - }, - "symbol-observable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", - "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==" - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "tailwindcss": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", - "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", - "requires": { - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "color-name": "^1.1.4", - "detective": "^5.2.1", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.2.12", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "lilconfig": "^2.0.6", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.18", - "postcss-import": "^14.1.0", - "postcss-js": "^4.0.0", - "postcss-load-config": "^3.1.4", - "postcss-nested": "6.0.0", - "postcss-selector-parser": "^6.0.10", - "postcss-value-parser": "^4.2.0", - "quick-lru": "^5.1.1", - "resolve": "^1.22.1" - }, - "dependencies": { - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - } - } - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" - }, - "temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==" - }, - "tempy": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", - "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", - "requires": { - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "dependencies": { - "type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==" - } - } - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "terser": { - "version": "5.30.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", - "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - } - } - }, - "terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "requires": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" - }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==" - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "dependencies": { - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" - } - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "requires": { - "punycode": "^2.1.1" - } - }, - "tryer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" - }, - "ts-invariant": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", - "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", - "requires": { - "tslib": "^2.1.0" - } - }, - "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" - } - } - }, - "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", - "peer": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" - }, - "unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" - }, - "unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" - }, - "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "requires": { - "makeerror": "1.0.12" - } - }, - "watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "web-vitals": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", - "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" - }, - "webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", - "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - } - } - }, - "webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "requires": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - } - } - }, - "webpack-dev-server": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", - "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", - "requires": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" - }, - "dependencies": { - "ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - }, - "ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "requires": {} - } - } - }, - "webpack-manifest-plugin": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", - "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", - "requires": { - "tapable": "^2.0.0", - "webpack-sources": "^2.2.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "webpack-sources": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", - "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - } - } - }, - "webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "requires": { - "iconv-lite": "0.4.24" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", - "requires": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" - } - }, - "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==" - }, - "workbox-background-sync": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", - "integrity": "sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==", - "requires": { - "idb": "^7.0.1", - "workbox-core": "6.5.4" - } - }, - "workbox-broadcast-update": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz", - "integrity": "sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==", - "requires": { - "workbox-core": "6.5.4" - } - }, - "workbox-build": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.4.tgz", - "integrity": "sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==", - "requires": { - "@apideck/better-ajv-errors": "^0.3.1", - "@babel/core": "^7.11.1", - "@babel/preset-env": "^7.11.0", - "@babel/runtime": "^7.11.2", - "@rollup/plugin-babel": "^5.2.0", - "@rollup/plugin-node-resolve": "^11.2.1", - "@rollup/plugin-replace": "^2.4.1", - "@surma/rollup-plugin-off-main-thread": "^2.2.3", - "ajv": "^8.6.0", - "common-tags": "^1.8.0", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^9.0.1", - "glob": "^7.1.6", - "lodash": "^4.17.20", - "pretty-bytes": "^5.3.0", - "rollup": "^2.43.1", - "rollup-plugin-terser": "^7.0.0", - "source-map": "^0.8.0-beta.0", - "stringify-object": "^3.3.0", - "strip-comments": "^2.0.1", - "tempy": "^0.6.0", - "upath": "^1.2.0", - "workbox-background-sync": "6.5.4", - "workbox-broadcast-update": "6.5.4", - "workbox-cacheable-response": "6.5.4", - "workbox-core": "6.5.4", - "workbox-expiration": "6.5.4", - "workbox-google-analytics": "6.5.4", - "workbox-navigation-preload": "6.5.4", - "workbox-precaching": "6.5.4", - "workbox-range-requests": "6.5.4", - "workbox-recipes": "6.5.4", - "workbox-routing": "6.5.4", - "workbox-strategies": "6.5.4", - "workbox-streams": "6.5.4", - "workbox-sw": "6.5.4", - "workbox-window": "6.5.4" - }, - "dependencies": { - "@apideck/better-ajv-errors": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", - "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", - "requires": { - "json-schema": "^0.4.0", - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - } - }, - "ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "requires": { - "whatwg-url": "^7.0.0" - } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "requires": { - "punycode": "^2.1.0" - } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } - } - }, - "workbox-cacheable-response": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz", - "integrity": "sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==", - "requires": { - "workbox-core": "6.5.4" - } - }, - "workbox-core": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", - "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" - }, - "workbox-expiration": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.4.tgz", - "integrity": "sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==", - "requires": { - "idb": "^7.0.1", - "workbox-core": "6.5.4" - } - }, - "workbox-google-analytics": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz", - "integrity": "sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==", - "requires": { - "workbox-background-sync": "6.5.4", - "workbox-core": "6.5.4", - "workbox-routing": "6.5.4", - "workbox-strategies": "6.5.4" - } - }, - "workbox-navigation-preload": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz", - "integrity": "sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==", - "requires": { - "workbox-core": "6.5.4" - } - }, - "workbox-precaching": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.4.tgz", - "integrity": "sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==", - "requires": { - "workbox-core": "6.5.4", - "workbox-routing": "6.5.4", - "workbox-strategies": "6.5.4" - } - }, - "workbox-range-requests": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz", - "integrity": "sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==", - "requires": { - "workbox-core": "6.5.4" - } - }, - "workbox-recipes": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.4.tgz", - "integrity": "sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==", - "requires": { - "workbox-cacheable-response": "6.5.4", - "workbox-core": "6.5.4", - "workbox-expiration": "6.5.4", - "workbox-precaching": "6.5.4", - "workbox-routing": "6.5.4", - "workbox-strategies": "6.5.4" - } - }, - "workbox-routing": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz", - "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", - "requires": { - "workbox-core": "6.5.4" - } - }, - "workbox-strategies": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz", - "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", - "requires": { - "workbox-core": "6.5.4" - } - }, - "workbox-streams": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.4.tgz", - "integrity": "sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==", - "requires": { - "workbox-core": "6.5.4", - "workbox-routing": "6.5.4" - } - }, - "workbox-sw": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz", - "integrity": "sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==" - }, - "workbox-webpack-plugin": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz", - "integrity": "sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg==", - "requires": { - "fast-json-stable-stringify": "^2.1.0", - "pretty-bytes": "^5.4.1", - "upath": "^1.2.0", - "webpack-sources": "^1.4.3", - "workbox-build": "6.5.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - } - } - }, - "workbox-window": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz", - "integrity": "sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==", - "requires": { - "@types/trusted-types": "^2.0.2", - "workbox-core": "6.5.4" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "requires": {} - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - }, - "zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" - }, - "zen-observable-ts": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz", - "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==", - "requires": { - "zen-observable": "0.8.15" - } - } } } diff --git a/bbb-graphql-client-test/src/App.js b/bbb-graphql-client-test/src/App.js index aacb485f94..4bc8092ecf 100644 --- a/bbb-graphql-client-test/src/App.js +++ b/bbb-graphql-client-test/src/App.js @@ -5,7 +5,6 @@ import './App.css'; import { SubscriptionClient } from 'subscriptions-transport-ws'; import Auth from "./Auth"; - function App() { const [sessionToken, setSessionToken] = useState(null); const [userId, setUserId] = useState(null); @@ -19,7 +18,6 @@ function App() { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); - const findSessionToken = async () => { if (urlParams.has('sessionToken')) { const sessionTokenFromUrl = urlParams.get('sessionToken'); @@ -36,6 +34,16 @@ function App() { findSessionToken(); },[]); + function generateRandomString(length) { + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result = ''; + const charactersLength = characters.length; + for (let i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; + } + async function connectGraphqlServer(sessionToken) { if(sessionToken == null) return; console.log('connectGraphqlServer'); @@ -46,7 +54,9 @@ function App() { connectionParams: { headers: { 'X-Session-Token': sessionToken, - 'json-patch-supported': 'true' + 'X-ClientSessionUUID': generateRandomString(15), + 'X-ClientType': 'HTML5', + 'X-ClientIsMobile': 'false' } }, connectionCallback: (error) => { @@ -102,7 +112,6 @@ function App() { },[sessionToken]); - return (

{graphqlClient && graphqlConnected ? ( diff --git a/bbb-graphql-client-test/src/Auth.js b/bbb-graphql-client-test/src/Auth.js index 75fbdea162..cea8973de1 100644 --- a/bbb-graphql-client-test/src/Auth.js +++ b/bbb-graphql-client-test/src/Auth.js @@ -1,12 +1,12 @@ -import {gql, useMutation, useSubscription} from '@apollo/client'; +import { gql, useMutation, useSubscription } from "@apollo/client"; import React from "react"; -import UserList from './UserList'; -import MeetingInfo from './MeetingInfo'; -import TotalOfUsers from './TotalOfUsers'; -import TotalOfModerators from './TotalOfModerators'; -import TotalOfViewers from './TotalOfViewers'; -import TotalOfUsersTalking from './TotalOfUsersTalking'; -import TotalOfUniqueNames from './TotalOfUniqueNames'; +import UserList from "./UserList"; +import MeetingInfo from "./MeetingInfo"; +import TotalOfUsers from "./TotalOfUsers"; +import TotalOfModerators from "./TotalOfModerators"; +import TotalOfViewers from "./TotalOfViewers"; +import TotalOfUsersTalking from "./TotalOfUsersTalking"; +import TotalOfUniqueNames from "./TotalOfUniqueNames"; import ChatMessages from "./ChatMessages"; import ChatsInfo from "./ChatsInfo"; import ChatPublicMessages from "./ChatPublicMessages"; @@ -23,61 +23,53 @@ import UserConnectionStatusReport from "./UserConnectionStatusReport"; import PresPresentationUploadToken from "./PresPresentationUploadToken"; export default function Auth() { - - //where is not necessary once user can update only its own status - //Hasura accepts "now()" as value to timestamp fields - const [updateUserClientEchoTestRunningAtMeAsNow] = useMutation(gql` - mutation UpdateUserClientEchoTestRunningAt { - update_user_current( - where: {} - _set: { echoTestRunningAt: "now()" } - ) { - affected_rows - } + //where is not necessary once user can update only its own status + //Hasura accepts "now()" as value to timestamp fields + const [updateUserClientEchoTestRunningAtMeAsNow] = useMutation(gql` + mutation UpdateUserClientEchoTestRunningAt { + update_user_current(where: {}, _set: { echoTestRunningAt: "now()" }) { + affected_rows } - `); + } + `); - const handleUpdateUserEchoTestRunningAt = () => { - updateUserClientEchoTestRunningAtMeAsNow(); - }; + const handleUpdateUserEchoTestRunningAt = () => { + updateUserClientEchoTestRunningAtMeAsNow(); + }; - const [dispatchUserJoin] = useMutation(gql` - mutation UserJoin($authToken: String!, $clientType: String!) { - userJoinMeeting( - authToken: $authToken, - clientType: $clientType, - ) - } - `); + const [dispatchUserJoin] = useMutation(gql` + mutation UserJoin($authToken: String!, $clientType: String!) { + userJoinMeeting(authToken: $authToken, clientType: $clientType) + } + `); - const handleDispatchUserJoin = (authToken) => { - dispatchUserJoin({ - variables: { - authToken: authToken, - clientType: 'HTML5', - }, - }); - }; + const handleDispatchUserJoin = (authToken) => { + dispatchUserJoin({ + variables: { + authToken: authToken, + clientType: "HTML5", + }, + }); + }; - const [dispatchUserLeave] = useMutation(gql` - mutation UserLeaveMeeting { - userLeaveMeeting - } - `); - const handleDispatchUserLeave = (authToken) => { - dispatchUserLeave(); - }; + const [dispatchUserLeave] = useMutation(gql` + mutation UserLeaveMeeting { + userLeaveMeeting + } + `); + const handleDispatchUserLeave = (authToken) => { + dispatchUserLeave(); + }; - - const { loading, error, data } = useSubscription( - gql`subscription { + const { loading, error, data } = useSubscription(gql` + subscription { user_current { userId authToken name loggedOut ejected - isOnline + currentlyInMeeting isModerator joined joinErrorCode @@ -88,122 +80,155 @@ export default function Auth() { positionInWaitingQueue } meeting { - name - ended - learningDashboard { - learningDashboardAccessToken - } + name + ended + learningDashboard { + learningDashboardAccessToken + } } } - }` - ); + } + `); - if(!loading && !error) { + if (!loading && !error) { + if (!data.hasOwnProperty("user_current") || data.user_current.length == 0) { + return ( +
+
+ Error: User not found +
+ ); + } - if(!data.hasOwnProperty('user_current') || - data.user_current.length == 0 - ) { - return

Error: User not found
; - } - - return (
+ return ( +

{data.user_current.map((curr) => { - console.log('user_current', curr); + console.log("user_current", curr); - if(curr.meeting.ended) { - return
- {curr.meeting.name} -

- Meeting has ended.
- } else if(curr.ejected) { - return
- {curr.meeting.name} -

- You left the meeting.
- } else if(curr.ejected) { - return
- {curr.meeting.name} -

- You were ejected from the meeting.
- } else if(curr.guestStatus !== 'ALLOW') { - return
- {curr.meeting.name} -

- You are waiting for approval. - {curr.guestStatusDetails.guestLobbyMessage} - Your position is: {curr.guestStatusDetails.positionInWaitingQueue} -
- } else if(curr.loggedOut) { - return
- {curr.meeting.name} -

- You left the meeting. -
- } else if(!curr.joined) { - return
- {curr.meeting.name} -

- You didn't join yet. - -
- } else if(curr.isOnline) { - return
- {curr.meeting.name} -

- You are online, welcome {curr.name} ({curr.userId}) - + if (curr.meeting.ended) { + return ( +
+ {curr.meeting.name} +
+
+ Meeting has ended. +
+ ); + } else if (curr.ejected) { + return ( +
+ {curr.meeting.name} +
+
+ You left the meeting. +
+ ); + } else if (curr.ejected) { + return ( +
+ {curr.meeting.name} +
+
+ You were ejected from the meeting. +
+ ); + } else if (curr.guestStatus !== "ALLOW") { + return ( +
+ {curr.meeting.name} +
+
+ You are waiting for approval. + {curr.guestStatusDetails.guestLobbyMessage} + + Your position is:{" "} + {curr.guestStatusDetails.positionInWaitingQueue} + +
+ ); + } else if (curr.loggedOut) { + return ( +
+ {curr.meeting.name} +
+
+ You left the meeting. +
+ ); + } else if (!curr.joined) { + return ( +
+ {curr.meeting.name} +
+
+ You didn't join yet. + +
+ ); + } else if (curr.currentlyInMeeting) { + return ( +
+ {curr.meeting.name} +
+
+ + You are online, welcome {curr.name} ({curr.userId}) + + - -
+ +
- -
+ +
- - - - - -
- + + + + + +
+ -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- - -
- - -
- -
- } +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ ); + } })} -
) +
+ ); } } - diff --git a/bbb-graphql-client-test/src/UserConnectionStatus.js b/bbb-graphql-client-test/src/UserConnectionStatus.js index 26c7fd9047..316a029fb9 100644 --- a/bbb-graphql-client-test/src/UserConnectionStatus.js +++ b/bbb-graphql-client-test/src/UserConnectionStatus.js @@ -3,7 +3,7 @@ import React, {useEffect, useState, useRef } from "react"; import {applyPatch} from "fast-json-patch"; export default function UserConnectionStatus() { - const networkRttInMs = useRef(null); // Ref to store the current timeout + const networkRttInMs = useRef(0); // Ref to store the current timeout const lastStatusUpdatedAtReceived = useRef(null); // Ref to store the current timeout //example specifying where and time (new Date().toISOString()) @@ -24,36 +24,23 @@ export default function UserConnectionStatus() { - //where is not necessary once user can update only its own status - //Hasura accepts "now()" as value to timestamp fields - const [updateUserClientResponseAtToMeAsNow] = useMutation(gql` - mutation UpdateConnectionRtt($networkRttInMs: Float!) { - userSetConnectionRtt( + const [updateConnectionAliveAtToMeAsNow] = useMutation(gql` + mutation UpdateConnectionAliveAt($networkRttInMs: Float!) { + userSetConnectionAlive( networkRttInMs: $networkRttInMs ) } `); - const handleUpdateUserClientResponseAt = () => { - updateUserClientResponseAtToMeAsNow({ - variables: { - networkRttInMs: networkRttInMs.current - }, - }); - }; - - - const [updateConnectionAliveAtToMeAsNow] = useMutation(gql` - mutation UpdateConnectionAliveAt { - userSetConnectionAlive - } - `); - const handleUpdateConnectionAliveAt = () => { const startTime = performance.now(); try { - updateConnectionAliveAtToMeAsNow().then(result => { + updateConnectionAliveAtToMeAsNow({ + variables: { + networkRttInMs: networkRttInMs.current + }, + }).then(result => { const endTime = performance.now(); networkRttInMs.current = endTime - startTime; @@ -120,7 +107,7 @@ export default function UserConnectionStatus() { lastStatusUpdatedAtReceived.current = curr.statusUpdatedAt; // setLastStatusUpdatedAtReceived(curr.statusUpdatedAt); - handleUpdateUserClientResponseAt(); + // handleUpdateUserClientResponseAt(); } return ( diff --git a/bbb-graphql-middleware/README.md b/bbb-graphql-middleware/README.md index 6d66da963c..e7a2f6af1d 100644 --- a/bbb-graphql-middleware/README.md +++ b/bbb-graphql-middleware/README.md @@ -1 +1 @@ -# bbb-graphql-middleware \ No newline at end of file +# bbb-graphql-middleware diff --git a/bbb-graphql-middleware/cmd/bbb-graphql-middleware/main.go b/bbb-graphql-middleware/cmd/bbb-graphql-middleware/main.go index dab9c60f54..4fc4ed27ef 100644 --- a/bbb-graphql-middleware/cmd/bbb-graphql-middleware/main.go +++ b/bbb-graphql-middleware/cmd/bbb-graphql-middleware/main.go @@ -1,23 +1,24 @@ package main import ( + "bbb-graphql-middleware/config" + "bbb-graphql-middleware/internal/common" + "bbb-graphql-middleware/internal/websrv" "context" "errors" "fmt" - "github.com/iMDT/bbb-graphql-middleware/internal/common" - "github.com/iMDT/bbb-graphql-middleware/internal/msgpatch" - "github.com/iMDT/bbb-graphql-middleware/internal/websrv" + "github.com/prometheus/client_golang/prometheus/promhttp" log "github.com/sirupsen/logrus" "net/http" - "os" - "strconv" "time" ) func main() { + cfg := config.GetConfig() + // Configure logger - if logLevelFromEnvVar, err := log.ParseLevel(os.Getenv("BBB_GRAPHQL_MIDDLEWARE_LOG_LEVEL")); err == nil { - log.SetLevel(logLevelFromEnvVar) + if logLevelFromConfig, err := log.ParseLevel(cfg.LogLevel); err == nil { + log.SetLevel(logLevelFromConfig) } else { log.SetLevel(log.InfoLevel) } @@ -25,57 +26,28 @@ func main() { log.SetFormatter(&log.JSONFormatter{}) log := log.WithField("_routine", "main") - if activitiesOverviewEnabled := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_ACTIVITIES_OVERVIEW_ENABLED"); activitiesOverviewEnabled == "true" { - go common.ActivitiesOverviewLogRoutine() - //go common.JsonPatchBenchmarkingLogRoutine() - } - common.InitUniqueID() log = log.WithField("graphql-middleware-uid", common.GetUniqueID()) log.Infof("Logger level=%v", log.Logger.Level) - //Clear cache from last exec - msgpatch.ClearAllCaches() - // Listen msgs from akka (for example to invalidate connection) go websrv.StartRedisListener() - if jsonPatchDisabled := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_JSON_PATCH_DISABLED"); jsonPatchDisabled != "" { + if cfg.Server.JsonPatchDisabled { log.Infof("Json Patch Disabled!") } // Websocket listener - //Define IP to listen - listenIp := "127.0.0.1" - if envListenIp := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_LISTEN_IP"); envListenIp != "" { - listenIp = envListenIp - } - - // Define port to listen on - listenPort := 8378 - if envListenPort := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_LISTEN_PORT"); envListenPort != "" { - if envListenPortAsInt, err := strconv.Atoi(envListenPort); err == nil { - listenPort = envListenPortAsInt - } - } - - //Define new Connections Rate Limit - maxConnPerSecond := 10 - if envMaxConnPerSecond := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_MAX_CONN_PER_SECOND"); envMaxConnPerSecond != "" { - if envMaxConnPerSecondAsInt, err := strconv.Atoi(envMaxConnPerSecond); err == nil { - maxConnPerSecond = envMaxConnPerSecondAsInt - } - } - rateLimiter := common.NewCustomRateLimiter(maxConnPerSecond) - - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + rateLimiter := common.NewCustomRateLimiter(cfg.Server.MaxConnectionsPerSecond) + http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 120*time.Second) defer cancel() - common.ActivitiesOverviewStarted("__WebsocketConnection") - defer common.ActivitiesOverviewCompleted("__WebsocketConnection") + common.HttpConnectionGauge.Inc() + common.HttpConnectionCounter.Inc() + defer common.HttpConnectionGauge.Dec() if err := rateLimiter.Wait(ctx); err != nil { if !errors.Is(err, context.Canceled) { @@ -88,7 +60,9 @@ func main() { websrv.ConnectionHandler(w, r) }) - log.Infof("listening on %v:%v", listenIp, listenPort) - log.Fatal(http.ListenAndServe(fmt.Sprintf("%v:%v", listenIp, listenPort), nil)) + // Add Prometheus metrics endpoint + http.Handle("/metrics", promhttp.Handler()) + log.Infof("listening on %v:%v", cfg.Server.Host, cfg.Server.Port) + log.Fatal(http.ListenAndServe(fmt.Sprintf("%v:%v", cfg.Server.Host, cfg.Server.Port), nil)) } diff --git a/bbb-graphql-middleware/config/Config.go b/bbb-graphql-middleware/config/Config.go new file mode 100644 index 0000000000..8b4e8ac1c9 --- /dev/null +++ b/bbb-graphql-middleware/config/Config.go @@ -0,0 +1,102 @@ +package config + +import ( + "dario.cat/mergo" + log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v3" + "io/ioutil" + "os" + "path/filepath" + "sync" +) + +var ( + instance *Config + once sync.Once +) + +var DefaultConfigPath = "/usr/share/bbb-graphql-middleware/config.yml" +var OverrideConfigPath = "/etc/bigbluebutton/bbb-graphql-middleware.yml" + +type Config struct { + Server struct { + Host string `yaml:"listen_host"` + Port int `yaml:"listen_port"` + MaxConnections int `yaml:"max_connections"` + MaxConnectionsPerSecond int `yaml:"max_connections_per_session_token"` + MaxConnectionsPerSessionToken int `yaml:"max_connections_per_second"` + AuthorizedCrossOrigin string `yaml:"authorized_cross_origin"` + JsonPatchDisabled bool `yaml:"json_patch_disabled"` + SubscriptionAllowedList string `yaml:"subscriptions_allowed_list"` + SubscriptionsDeniedList string `yaml:"subscriptions_denied_list"` + } `yaml:"server"` + Redis struct { + Host string `yaml:"host"` + Port int32 `yaml:"port"` + Password string `yaml:"password"` + } `yaml:"redis"` + Hasura struct { + Url string `yaml:"url"` + } `yaml:"hasura"` + GraphqlActions struct { + Url string `yaml:"url"` + } `yaml:"graphql-actions"` + AuthHook struct { + Url string `yaml:"url"` + } `yaml:"auth_hook"` + SessionVarsHook struct { + Url string `yaml:"url"` + } `yaml:"session_vars_hook"` + LogLevel string `yaml:"log_level"` + PrometheusAdvancedMetricsEnabled bool `yaml:"prometheus_advanced_metrics_enabled"` +} + +func GetConfig() *Config { + once.Do(func() { + instance = &Config{} + instance.loadConfigs() + }) + return instance +} + +func (c *Config) loadConfigs() { + // Load default config file + configDefault, err := loadConfigFile(DefaultConfigPath) + if err != nil { + log.Fatalf("Error while loading config file (%s): %v", DefaultConfigPath, err) + } + + // Load override config file if exists + if _, err := os.Stat(OverrideConfigPath); err == nil { + configOverride, err := loadConfigFile(OverrideConfigPath) + if err != nil { + log.Fatalf("Error while loading override config file (%s): %v", OverrideConfigPath, err) + } + + log.Info("Override config found at " + OverrideConfigPath) + + // Use mergo to merge configs + err = mergo.Merge(&configDefault, configOverride, mergo.WithOverride) + if err != nil { + log.Fatalf("Erro ao mesclar as configurações: %v", err) + } + } + + // Update the singleton instance with the merged config + *instance = configDefault +} + +func loadConfigFile(path string) (Config, error) { + var config Config + data, err := ioutil.ReadFile(filepath.Clean(path)) + if err != nil { + return config, err + } + + err = yaml.Unmarshal(data, &config) + if err != nil { + return config, err + } + + return config, nil +} diff --git a/bbb-graphql-middleware/config/config.yml b/bbb-graphql-middleware/config/config.yml new file mode 100644 index 0000000000..0cda076e7c --- /dev/null +++ b/bbb-graphql-middleware/config/config.yml @@ -0,0 +1,28 @@ +server: + listen_host: 127.0.0.1 + listen_port: 8378 + #max of concurrent connections + max_connections: 500 + max_connections_per_session_token: 3 + #rate limit + max_connections_per_second: 100 + # If you are running a cluster proxy setup, you need to allow the url of the Frontend + # Add an Authorized Cross Origin. See https://docs.bigbluebutton.org/administration/cluster-proxy + #authorized_cross_origin: 'bbb-proxy.example.com' + json_patch_disabled: false + subscriptions_allowed_list: + subscriptions_denied_list: +redis: + host: 127.0.0.1 + port: 6379 + password: "" +hasura: + url: ws://127.0.0.1:8085/v1/graphql +graphql-actions: + url: http://127.0.0.1:8093 +auth_hook: + url: http://127.0.0.1:8090/bigbluebutton/connection/checkGraphqlAuthorization +session_vars_hook: + url: http://127.0.0.1:8901/userInfo +prometheus_advanced_metrics_enabled: false +log_level: INFO diff --git a/bbb-graphql-middleware/demo/client/main.js b/bbb-graphql-middleware/demo/client/main.js index 1173fa6f0c..7cbcbb55ea 100644 --- a/bbb-graphql-middleware/demo/client/main.js +++ b/bbb-graphql-middleware/demo/client/main.js @@ -31,7 +31,7 @@ ws.onopen = (event) => { const payload = { variables:{}, extensions: {}, query: query }; // console.log(`Sending: ${JSON.stringify(payload)}`); - ws.send(JSON.stringify({id:"1", type: "start", payload })); + ws.send(JSON.stringify({id:"1", type: "subscribe", payload })); } diff --git a/bbb-graphql-middleware/demo/client/package-lock.json b/bbb-graphql-middleware/demo/client/package-lock.json index 14a4b02b37..a87083f759 100644 --- a/bbb-graphql-middleware/demo/client/package-lock.json +++ b/bbb-graphql-middleware/demo/client/package-lock.json @@ -9,13 +9,14 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "ws": "^8.13.0" + "ws": "^8.17.1" } }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -35,9 +36,9 @@ }, "dependencies": { "ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "requires": {} } } diff --git a/bbb-graphql-middleware/demo/client/package.json b/bbb-graphql-middleware/demo/client/package.json index cbecd8f68b..eaf8117e69 100644 --- a/bbb-graphql-middleware/demo/client/package.json +++ b/bbb-graphql-middleware/demo/client/package.json @@ -10,6 +10,6 @@ "author": "", "license": "ISC", "dependencies": { - "ws": "^8.13.0" + "ws": "^8.17.1" } } diff --git a/bbb-graphql-middleware/go.mod b/bbb-graphql-middleware/go.mod index 8ae5fcbb7e..176e7380f4 100644 --- a/bbb-graphql-middleware/go.mod +++ b/bbb-graphql-middleware/go.mod @@ -1,20 +1,29 @@ -module github.com/iMDT/bbb-graphql-middleware +module bbb-graphql-middleware -go 1.20 +go 1.22.5 require ( + dario.cat/mergo v1.0.1 github.com/evanphx/json-patch v0.5.2 github.com/google/uuid v1.6.0 - github.com/mattbaird/jsonpatch v0.0.0-20230413205102-771768614e91 - github.com/redis/go-redis/v9 v9.0.3 - github.com/sirupsen/logrus v1.9.0 - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 - nhooyr.io/websocket v1.8.10 + github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38 + github.com/prometheus/client_golang v1.19.1 + github.com/redis/go-redis/v9 v9.6.1 + github.com/sirupsen/logrus v1.9.3 + golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 + gopkg.in/yaml.v3 v3.0.1 + nhooyr.io/websocket v1.8.11 ) require ( + github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/kr/text v0.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + golang.org/x/sys v0.17.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect ) diff --git a/bbb-graphql-middleware/go.sum b/bbb-graphql-middleware/go.sum index 2bdcf8adf4..c1a0559211 100644 --- a/bbb-graphql-middleware/go.sum +++ b/bbb-graphql-middleware/go.sum @@ -1,7 +1,14 @@ -github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= -github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -9,28 +16,50 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/mattbaird/jsonpatch v0.0.0-20230413205102-771768614e91 h1:JnZSkFP1/GLwKCEuuWVhsacvbDQIVa5BRwAwd+9k2Vw= -github.com/mattbaird/jsonpatch v0.0.0-20230413205102-771768614e91/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38 h1:hQWBtNqRYrI7CWIaUSXXtNKR90KzcUA5uiuxFVWw7sU= +github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/redis/go-redis/v9 v9.0.3 h1:+7mmR26M0IvyLxGZUHxu4GiBkJkVDid0Un+j4ScYu4k= -github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= -nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= +nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/bbb-graphql-middleware/install-graphql-middleware.sh b/bbb-graphql-middleware/install-graphql-middleware.sh deleted file mode 100755 index 4c03f069ca..0000000000 --- a/bbb-graphql-middleware/install-graphql-middleware.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -if [ "$EUID" -ne 0 ]; then - echo "Please run this script as root ( or with sudo )" ; - exit 1; -fi; - -cd "$(dirname "$0")" - -#Install Go -#sudo apt install golang -y -GO_VERSION=1.20.8 -wget --no-verbose https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz \ - && tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz \ - && rm go${GO_VERSION}.linux-amd64.tar.gz \ - && ln -sf /usr/local/go/bin/go /usr/bin/go - -go version - -# Build Graphql Middleware -./local-build.sh -mv bbb-graphql-middleware /usr/local/bin/bbb-graphql-middleware - -# Create service bbb-graphql-middleware -cp ./bbb-graphql-middleware-config.env /etc/default/bbb-graphql-middleware -cp ./bbb-graphql-middleware.service /lib/systemd/system/bbb-graphql-middleware.service -systemctl enable bbb-graphql-middleware -systemctl start bbb-graphql-middleware - - -# Set nginx location -cp ./graphql.nginx /usr/share/bigbluebutton/nginx -systemctl restart nginx - - -echo "" -echo "" -echo "Bbb-graphql-middleware Installed!" diff --git a/bbb-graphql-middleware/internal/akka_apps/client.go b/bbb-graphql-middleware/internal/akka_apps/client.go new file mode 100644 index 0000000000..16bb65ff85 --- /dev/null +++ b/bbb-graphql-middleware/internal/akka_apps/client.go @@ -0,0 +1,75 @@ +package akka_apps + +import ( + "bbb-graphql-middleware/config" + "encoding/json" + "fmt" + log "github.com/sirupsen/logrus" + "io/ioutil" + "net/http" + "strings" +) + +// sessionVarsHookUrl is the authentication hook URL obtained from an environment variable. +var sessionVarsHookUrl = config.GetConfig().SessionVarsHook.Url + +func AkkaAppsGetSessionVariablesFrom(browserConnectionId string, sessionToken string) (map[string]string, error) { + logger := log.WithField("_routine", "AkkaAppsClient").WithField("browserConnectionId", browserConnectionId) + logger.Debug("Starting AkkaAppsClient") + defer logger.Debug("Finished AkkaAppsClient") + + // Create a new HTTP client with a cookie jar. + client := &http.Client{} + + // Check if the authentication hook URL is set. + if sessionVarsHookUrl == "" { + return nil, fmt.Errorf("BBB_GRAPHQL_MIDDLEWARE_SESSION_VARS_HOOK_URL not set") + } + + log.Trace("Get user session vars from: " + sessionVarsHookUrl + "?sessionToken=" + sessionToken) + + // Create a new HTTP request to the authentication hook URL. + req, err := http.NewRequest("GET", sessionVarsHookUrl, nil) + if err != nil { + return nil, err + } + + // Execute the HTTP request to obtain user session variables (like X-Hasura-Role) + req.Header.Set("x-session-token", sessionToken) + req.Header.Set("User-Agent", "bbb-graphql-middleware") + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var respBodyAsMap map[string]string + if err := json.Unmarshal(respBody, &respBodyAsMap); err != nil { + return nil, err + } + + // Check the response status. + response, ok := respBodyAsMap["response"] + if !ok { + return nil, fmt.Errorf("response key not found in the parsed object") + } + if response != "authorized" { + logger.Error(response) + return nil, fmt.Errorf("user not authorized") + } + + // Normalize the response header keys. + normalizedResponse := make(map[string]string) + for key, value := range respBodyAsMap { + if strings.HasPrefix(strings.ToLower(key), "x-hasura") { + normalizedResponse[strings.ToLower(key)] = value + } + } + + return normalizedResponse, nil +} diff --git a/bbb-graphql-middleware/internal/bbb_web/client.go b/bbb-graphql-middleware/internal/bbb_web/client.go index 5fffb1b31d..7e45dcdd62 100644 --- a/bbb-graphql-middleware/internal/bbb_web/client.go +++ b/bbb-graphql-middleware/internal/bbb_web/client.go @@ -1,44 +1,40 @@ package bbb_web import ( + "bbb-graphql-middleware/config" "encoding/json" "fmt" + log "github.com/sirupsen/logrus" "io/ioutil" "net/http" "net/http/cookiejar" - "os" "strings" - "time" - - "github.com/iMDT/bbb-graphql-middleware/internal/common" - log "github.com/sirupsen/logrus" ) // authHookUrl is the authentication hook URL obtained from an environment variable. -var authHookUrl = os.Getenv("BBB_GRAPHQL_MIDDLEWARE_AUTH_HOOK_URL") +var authHookUrl = config.GetConfig().AuthHook.Url -// BBBWebClient handles the web requests for authentication and returns a map of response headers. -func BBBWebClient(browserConnection *common.BrowserConnection, cookies []*http.Cookie) (map[string]string, error) { - logger := log.WithField("_routine", "BBBWebClient").WithField("browserConnectionId", browserConnection.Id) +func BBBWebCheckAuthorization(browserConnectionId string, sessionToken string, cookies []*http.Cookie) (string, string, error) { + logger := log.WithField("_routine", "BBBWebClient").WithField("browserConnectionId", browserConnectionId) logger.Debug("Starting BBBWebClient") defer logger.Debug("Finished BBBWebClient") // Create a new HTTP client with a cookie jar. jar, err := cookiejar.New(nil) if err != nil { - return nil, fmt.Errorf("failed to create cookie jar: %v", err) + return "", "", fmt.Errorf("failed to create cookie jar: %v", err) } client := &http.Client{Jar: jar} // Check if the authentication hook URL is set. if authHookUrl == "" { - return nil, fmt.Errorf("BBB_GRAPHQL_MIDDLEWARE_AUTH_HOOK_URL not set") + return "", "", fmt.Errorf("BBB_GRAPHQL_MIDDLEWARE_AUTH_HOOK_URL not set") } // Create a new HTTP request to the authentication hook URL. req, err := http.NewRequest("GET", authHookUrl, nil) if err != nil { - return nil, err + return "", "", err } // Add cookies to the request. @@ -46,46 +42,61 @@ func BBBWebClient(browserConnection *common.BrowserConnection, cookies []*http.C req.AddCookie(cookie) } - // Wait for SessionToken to be provided. - for browserConnection.SessionToken == "" { - time.Sleep(150 * time.Millisecond) - } - // Execute the HTTP request to obtain user session variables (like X-Hasura-Role) - req.Header.Set("x-session-token", browserConnection.SessionToken) - req.Header.Set("User-Agent", "hasura-graphql-engine") + //req.Header.Set("x-original-uri", authHookUrl+"?sessionToken="+sessionToken) + req.Header.Set("x-session-token", sessionToken) + //req.Header.Set("User-Agent", "hasura-graphql-engine") resp, err := client.Do(req) if err != nil { - return nil, err + return "", "", err } defer resp.Body.Close() respBody, err := ioutil.ReadAll(resp.Body) if err != nil { - return nil, err + return "", "", err } + log.Trace(string(respBody)) + var respBodyAsMap map[string]string if err := json.Unmarshal(respBody, &respBodyAsMap); err != nil { - return nil, err + return "", "", err } // Check the response status. response, ok := respBodyAsMap["response"] if !ok { - return nil, fmt.Errorf("response key not found in the parsed object") + return "", "", fmt.Errorf("response key not found in the parsed object") } if response != "authorized" { - return nil, fmt.Errorf("auth token not authorized") + logger.Error(response) + return "", "", fmt.Errorf("user not authorized") } // Normalize the response header keys. normalizedResponse := make(map[string]string) for key, value := range respBodyAsMap { - if strings.HasPrefix(strings.ToLower(key), "x-hasura") { + if strings.HasPrefix(strings.ToLower(key), "x-") { normalizedResponse[strings.ToLower(key)] = value } } - return normalizedResponse, nil + var userId string + var meetingId string + + //Get userId and meetingId from response Header + for key, value := range normalizedResponse { + log.Debug("%s: %s\n", key, value) + + if key == "x-userid" { + userId = value + } + + if key == "x-meetingid" { + meetingId = value + } + } + + return meetingId, userId, nil } diff --git a/bbb-graphql-middleware/internal/common/ActivitiesOverview.go b/bbb-graphql-middleware/internal/common/ActivitiesOverview.go deleted file mode 100644 index c58d3cd3c2..0000000000 --- a/bbb-graphql-middleware/internal/common/ActivitiesOverview.go +++ /dev/null @@ -1,155 +0,0 @@ -package common - -import ( - "encoding/json" - "fmt" - log "github.com/sirupsen/logrus" - "runtime" - "strings" - "sync" - "time" -) - -type ActivitiesOverviewObj struct { - Started int64 - Completed int64 - DataReceived int64 - DataSizeAvg int64 - DataSizeMax int64 - DataCountAvg int64 - DataCountMax int64 -} - -var ActivitiesOverviewEnabled = false -var activitiesOverview = make(map[string]ActivitiesOverviewObj) -var activitiesOverviewMux = sync.Mutex{} - -func ActivitiesOverviewStarted(index string) { - if !ActivitiesOverviewEnabled { - return - } - - activitiesOverviewMux.Lock() - defer activitiesOverviewMux.Unlock() - - if _, exists := activitiesOverview[index]; !exists { - activitiesOverview[index] = ActivitiesOverviewObj{ - Started: 0, - Completed: 0, - DataReceived: 0, - DataSizeAvg: 0, - DataSizeMax: 0, - DataCountAvg: 0, - DataCountMax: 0, - } - } - - updatedValues := activitiesOverview[index] - updatedValues.Started++ - - activitiesOverview[index] = updatedValues -} - -func ActivitiesOverviewDataReceived(index string) { - if !ActivitiesOverviewEnabled { - return - } - - activitiesOverviewMux.Lock() - defer activitiesOverviewMux.Unlock() - - if updatedValues, exists := activitiesOverview[index]; exists { - updatedValues.DataReceived++ - - activitiesOverview[index] = updatedValues - } -} - -func ActivitiesOverviewCompleted(index string) { - if !ActivitiesOverviewEnabled { - return - } - - activitiesOverviewMux.Lock() - defer activitiesOverviewMux.Unlock() - - if updatedValues, exists := activitiesOverview[index]; exists { - updatedValues.Completed++ - - activitiesOverview[index] = updatedValues - } -} - -func ActivitiesOverviewDataSize(index string, dataSize int64, dataCount int64) { - if !ActivitiesOverviewEnabled { - return - } - - activitiesOverviewMux.Lock() - defer activitiesOverviewMux.Unlock() - - if updatedValues, exists := activitiesOverview[index]; exists { - updatedValues.DataSizeAvg = ((updatedValues.DataSizeAvg * (updatedValues.DataReceived - 1)) + dataSize) / updatedValues.DataReceived - if dataSize > updatedValues.DataSizeMax { - updatedValues.DataSizeMax = dataSize - } - updatedValues.DataCountAvg = ((updatedValues.DataCountAvg * (updatedValues.DataReceived - 1)) + dataCount) / updatedValues.DataReceived - if dataCount > updatedValues.DataCountMax { - updatedValues.DataCountMax = dataCount - } - activitiesOverview[index] = updatedValues - } -} - -func GetActivitiesOverview() map[string]ActivitiesOverviewObj { - activitiesOverviewMux.Lock() - defer activitiesOverviewMux.Unlock() - - return activitiesOverview -} - -func ActivitiesOverviewLogRoutine() { - ActivitiesOverviewEnabled = true - log.Info("Activities Overview routine started!") - - for { - time.Sleep(5 * time.Second) - fmt.Println("===================================================") - - hasuraConnections := GetActivitiesOverview()["__HasuraConnection"].Started - topMessages := make(map[string]ActivitiesOverviewObj) - activitiesOverview := GetActivitiesOverview() - for index, item := range activitiesOverview { - if strings.HasPrefix(index, "_") || - item.Started > hasuraConnections*3 || - item.DataReceived > hasuraConnections*5 || - item.DataSizeAvg > 4000 || - item.DataSizeMax > 50000 || - item.DataCountAvg > 5 || - (item.DataCountMax > 10 && item.DataCountMax >= hasuraConnections) { - topMessages[index] = item - } - } - - jsonIndentOverviewBytes, err := json.MarshalIndent(topMessages, "", " ") - if err != nil { - log.Errorf("Error occurred during marshaling. Error: %s", err.Error()) - } - fmt.Println(string(jsonIndentOverviewBytes)) - - jsonOverviewBytes, err := json.Marshal(topMessages) - fmt.Println(string(jsonOverviewBytes)) - - //log.WithField("data", string(jsonOverviewBytes)).Info("Top Activities Overview") - - activitiesOverviewSummary := make(map[string]int64) - activitiesOverviewSummary["activeWsConnections"] = GetActivitiesOverview()["__WebsocketConnection"].Started - GetActivitiesOverview()["__WebsocketConnection"].Completed - activitiesOverviewSummary["activeBrowserHandlers"] = GetActivitiesOverview()["__BrowserConnection"].Started - GetActivitiesOverview()["__BrowserConnection"].Completed - activitiesOverviewSummary["activeSubscriptions"] = GetActivitiesOverview()["_Sum-subscription"].Started - GetActivitiesOverview()["_Sum-subscription"].Completed - activitiesOverviewSummary["pendingMutations"] = GetActivitiesOverview()["_Sum-mutation"].Started - GetActivitiesOverview()["_Sum-mutation"].Completed - activitiesOverviewSummary["numGoroutine"] = int64(runtime.NumGoroutine()) - jsonOverviewSummaryBytes, _ := json.MarshalIndent(activitiesOverviewSummary, "", "") - //log.WithField("data", string(jsonOverviewSummaryBytes)).Info("Activities Overview Summary") - fmt.Println(string(jsonOverviewSummaryBytes)) - } -} diff --git a/bbb-graphql-middleware/internal/common/CustomCache.go b/bbb-graphql-middleware/internal/common/CustomCache.go index 49c3003dfe..ad5ff752ec 100644 --- a/bbb-graphql-middleware/internal/common/CustomCache.go +++ b/bbb-graphql-middleware/internal/common/CustomCache.go @@ -7,17 +7,17 @@ import ( var GlobalCacheLocks = NewCacheLocks() type CacheLocks struct { - locks map[string]*sync.Mutex + locks map[uint32]*sync.Mutex mutex sync.Mutex // Protects the 'locks' map } func NewCacheLocks() *CacheLocks { return &CacheLocks{ - locks: make(map[string]*sync.Mutex), + locks: make(map[uint32]*sync.Mutex), } } -func (c *CacheLocks) Lock(id string) { +func (c *CacheLocks) Lock(id uint32) { c.mutex.Lock() if _, exists := c.locks[id]; !exists { c.locks[id] = &sync.Mutex{} @@ -28,7 +28,7 @@ func (c *CacheLocks) Lock(id string) { mtx.Lock() // Lock the specific ID mutex } -func (c *CacheLocks) Unlock(id string) { +func (c *CacheLocks) Unlock(id uint32) { c.mutex.Lock() if mtx, exists := c.locks[id]; exists { mtx.Unlock() diff --git a/bbb-graphql-middleware/internal/common/CustomJsonPatcher.go b/bbb-graphql-middleware/internal/common/CustomJsonPatcher.go index 7eb858d504..75109e98ec 100644 --- a/bbb-graphql-middleware/internal/common/CustomJsonPatcher.go +++ b/bbb-graphql-middleware/internal/common/CustomJsonPatcher.go @@ -1,6 +1,7 @@ package common import ( + "bytes" "encoding/json" "fmt" evanphxjsonpatch "github.com/evanphx/json-patch" @@ -8,46 +9,51 @@ import ( log "github.com/sirupsen/logrus" ) -func ValidateIfShouldUseCustomJsonPatch(original []byte, modified []byte, idFieldName string) bool { +func ValidateIfShouldUseCustomJsonPatch(original []byte, modified []byte, idFieldName string) (bool, []byte) { + //Temporarily use CustomPatch only for UserList (testing feature) + if !bytes.Contains(modified, []byte("\"__typename\":\"user\"}]")) { + return false, nil + } + //Test Original Data originalMap := GetMapFromByte(original) if originalMap == nil { - return false + return false, nil } if len(originalMap) <= 1 { - return false + return false, nil } firstItem := originalMap[0] if _, existsIdField := firstItem[idFieldName].(string); !existsIdField { - return false + return false, nil } if hasDuplicatedId(originalMap, idFieldName) { - return false + return false, nil } //Test Modified Data modifiedMap := GetMapFromByte(modified) if modifiedMap == nil { - return false + return false, nil } if len(modifiedMap) <= 1 { - return false + return false, nil } firstItem = modifiedMap[0] if _, existsIdField := firstItem[idFieldName].(string); !existsIdField { - return false + return false, nil } if hasDuplicatedId(modifiedMap, idFieldName) { - return false + return false, nil } - return true + return true, CreateJsonPatchFromMaps(originalMap, modifiedMap, modified, "userId") } func hasDuplicatedId(items []map[string]interface{}, idFieldName string) bool { @@ -67,12 +73,10 @@ func CreateJsonPatch(original []byte, modified []byte, idFieldName string) []byt originalMap := GetMapFromByte(original) modifiedMap := GetMapFromByte(modified) - return CreateJsonPatchFromMaps(originalMap, modifiedMap, idFieldName) + return CreateJsonPatchFromMaps(originalMap, modifiedMap, modified, idFieldName) } -func CreateJsonPatchFromMaps(original []map[string]interface{}, modified []map[string]interface{}, idFieldName string) []byte { - modifiedJson, _ := json.Marshal(modified) - +func CreateJsonPatchFromMaps(original []map[string]interface{}, modified []map[string]interface{}, modifiedJson []byte, idFieldName string) []byte { //CREATE PATCHES FOR OPERATION "REPLACE" replacesPatches, originalWithReplaces := CreateReplacePatches(original, modified, idFieldName) diff --git a/bbb-graphql-middleware/internal/common/GlobalState.go b/bbb-graphql-middleware/internal/common/GlobalState.go index ccbba9273d..b04a657b36 100644 --- a/bbb-graphql-middleware/internal/common/GlobalState.go +++ b/bbb-graphql-middleware/internal/common/GlobalState.go @@ -1,6 +1,7 @@ package common import ( + "bbb-graphql-middleware/config" "github.com/google/uuid" "sync" "time" @@ -16,31 +17,153 @@ func GetUniqueID() string { return uniqueID } -var JsonPatchCache = make(map[string][]byte) -var JsonPatchCacheMutex sync.RWMutex +var PatchedMessageCache = make(map[uint32][]byte) +var PatchedMessageCacheMutex sync.RWMutex -func GetJsonPatchCache(cacheKey string) ([]byte, bool) { - JsonPatchCacheMutex.RLock() - defer JsonPatchCacheMutex.RUnlock() +func GetPatchedMessageCache(cacheKey uint32) ([]byte, bool) { + PatchedMessageCacheMutex.RLock() + defer PatchedMessageCacheMutex.RUnlock() - jsonDiffPatch, jsonDiffPatchExists := JsonPatchCache[cacheKey] + jsonDiffPatch, jsonDiffPatchExists := PatchedMessageCache[cacheKey] return jsonDiffPatch, jsonDiffPatchExists } -func StoreJsonPatchCache(cacheKey string, data []byte) { - JsonPatchCacheMutex.Lock() - defer JsonPatchCacheMutex.Unlock() +func StorePatchedMessageCache(cacheKey uint32, data []byte) { + PatchedMessageCacheMutex.Lock() + defer PatchedMessageCacheMutex.Unlock() - JsonPatchCache[cacheKey] = data + PatchedMessageCache[cacheKey] = data //Remove the cache after 30 seconds - go RemoveJsonPatchCache(cacheKey, 30) + go RemovePatchedMessageCache(cacheKey, 30) } -func RemoveJsonPatchCache(cacheKey string, delayInSecs time.Duration) { +func RemovePatchedMessageCache(cacheKey uint32, delayInSecs time.Duration) { time.Sleep(delayInSecs * time.Second) - JsonPatchCacheMutex.Lock() - defer JsonPatchCacheMutex.Unlock() - delete(JsonPatchCache, cacheKey) + PatchedMessageCacheMutex.Lock() + defer PatchedMessageCacheMutex.Unlock() + delete(PatchedMessageCache, cacheKey) +} + +var HasuraMessageCache = make(map[uint32]HasuraMessage) +var HasuraMessageKeyCache = make(map[uint32]string) +var HasuraMessageCacheMutex sync.RWMutex + +func GetHasuraMessageCache(cacheKey uint32) (string, HasuraMessage, bool) { + HasuraMessageCacheMutex.RLock() + defer HasuraMessageCacheMutex.RUnlock() + + hasuraMessageDataKey, _ := HasuraMessageKeyCache[cacheKey] + hasuraMessage, hasuraMessageExists := HasuraMessageCache[cacheKey] + return hasuraMessageDataKey, hasuraMessage, hasuraMessageExists +} + +func StoreHasuraMessageCache(cacheKey uint32, dataKey string, hasuraMessage HasuraMessage) { + HasuraMessageCacheMutex.Lock() + defer HasuraMessageCacheMutex.Unlock() + + HasuraMessageKeyCache[cacheKey] = dataKey + HasuraMessageCache[cacheKey] = hasuraMessage + + //Remove the cache after 30 seconds + go RemoveHasuraMessageCache(cacheKey, 30) +} + +func RemoveHasuraMessageCache(cacheKey uint32, delayInSecs time.Duration) { + time.Sleep(delayInSecs * time.Second) + + HasuraMessageCacheMutex.Lock() + defer HasuraMessageCacheMutex.Unlock() + delete(HasuraMessageKeyCache, cacheKey) + delete(HasuraMessageCache, cacheKey) +} + +var StreamCursorValueCache = make(map[uint32]interface{}) +var StreamCursorValueCacheMutex sync.RWMutex + +func GetStreamCursorValueCache(cacheKey uint32) (interface{}, bool) { + StreamCursorValueCacheMutex.RLock() + defer StreamCursorValueCacheMutex.RUnlock() + + streamCursorValue, streamCursorValueExists := StreamCursorValueCache[cacheKey] + return streamCursorValue, streamCursorValueExists +} + +func StoreStreamCursorValueCache(cacheKey uint32, streamCursorValue interface{}) { + StreamCursorValueCacheMutex.Lock() + defer StreamCursorValueCacheMutex.Unlock() + + StreamCursorValueCache[cacheKey] = streamCursorValue + + //Remove the cache after 30 seconds + go RemoveStreamCursorValueCache(cacheKey, 30) +} + +func RemoveStreamCursorValueCache(cacheKey uint32, delayInSecs time.Duration) { + time.Sleep(delayInSecs * time.Second) + + StreamCursorValueCacheMutex.Lock() + defer StreamCursorValueCacheMutex.Unlock() + delete(StreamCursorValueCache, cacheKey) +} + +var MaxConnPerSessionToken = config.GetConfig().Server.MaxConnectionsPerSessionToken +var MaxConnGlobal = config.GetConfig().Server.MaxConnections + +func GetMaxConnectionsPerSessionToken() int { + return MaxConnPerSessionToken +} + +func GetMaxConnectionsGlobal() int { + return MaxConnGlobal +} + +var GlobalConnectionsCount int +var UserConnectionsCount = make(map[string]int) +var UserConnectionsCountMutex sync.RWMutex + +func HasReachedMaxGlobalConnections() bool { + if GetMaxConnectionsGlobal() == 0 { + return true + } + + return GlobalConnectionsCount >= GetMaxConnectionsGlobal() +} + +func GetUserConnectionCount(sessionToken string) (int, bool) { + UserConnectionsCountMutex.RLock() + defer UserConnectionsCountMutex.RUnlock() + + numOfConn, userConnExists := UserConnectionsCount[sessionToken] + return numOfConn, userConnExists +} + +func HasReachedMaxUserConnections(sessionToken string) bool { + if GetMaxConnectionsPerSessionToken() == 0 { + return true + } + + numOfConn, _ := GetUserConnectionCount(sessionToken) + + return numOfConn >= GetMaxConnectionsPerSessionToken() +} + +func AddUserConnection(sessionToken string) { + UserConnectionsCountMutex.Lock() + defer UserConnectionsCountMutex.Unlock() + + GlobalConnectionsCount++ + UserConnectionsCount[sessionToken]++ +} + +func RemoveUserConnection(sessionToken string) { + UserConnectionsCountMutex.Lock() + defer UserConnectionsCountMutex.Unlock() + + GlobalConnectionsCount-- + UserConnectionsCount[sessionToken]-- + if UserConnectionsCount[sessionToken] <= 0 { + delete(UserConnectionsCount, sessionToken) + } } diff --git a/bbb-graphql-middleware/internal/common/PrometheusMetrics.go b/bbb-graphql-middleware/internal/common/PrometheusMetrics.go new file mode 100644 index 0000000000..a5b2e16012 --- /dev/null +++ b/bbb-graphql-middleware/internal/common/PrometheusMetrics.go @@ -0,0 +1,95 @@ +package common + +import ( + "bbb-graphql-middleware/config" + "github.com/prometheus/client_golang/prometheus" +) + +var PrometheusAdvancedMetricsEnabled = config.GetConfig().PrometheusAdvancedMetricsEnabled + +var ( + HttpConnectionGauge = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "http_connection_active", + Help: "Number of active HTTP connections", + }) + HttpConnectionCounter = prometheus.NewCounter(prometheus.CounterOpts{ + Name: "http_connection_total", + Help: "Total number of HTTP connections", + }) + WsConnectionAcceptedCounter = prometheus.NewCounter(prometheus.CounterOpts{ + Name: "ws_connection_accepted", + Help: "Total number of Websocket connections accepted", + }) + WsConnectionRejectedCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "ws_connection_rejected", + Help: "Total number of Websocket connections rejected", + }, + []string{"reason"}, + ) + GqlSubscribeCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "gql_subscription_total", + Help: "Total number of Graphql subscriptions", + }, + []string{"type", "operationName"}, + ) + GqlMutationsCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "gql_mutation_total", + Help: "Total number of Graphql mutations", + }, + []string{"operationName"}, + ) + GqlReceivedDataCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "gql_received_data_total", + Help: "Frequency of updates of a given data", + }, + []string{"type", "operationName"}, + ) + GqlReceivedDataPayloadLength = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "gql_received_data_payload_length", + Help: "Length (number of positions) of received data payload", + Buckets: []float64{ + 1, + 10, + 50, + 100, + 300, + 600, + }, + }, + []string{"type", "operationName"}, + ) + GqlReceivedDataPayloadSize = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "gql_received_data_payload_size", + Help: "Size (in bytes) of received data payload", + Buckets: []float64{ + 200, + 600, + 1200, + 5000, + 10000, + 30000, + }, + }, + []string{"type", "operationName"}, + ) +) + +func init() { + prometheus.MustRegister(HttpConnectionGauge) + prometheus.MustRegister(HttpConnectionCounter) + prometheus.MustRegister(WsConnectionAcceptedCounter) + prometheus.MustRegister(WsConnectionRejectedCounter) + prometheus.MustRegister(GqlSubscribeCounter) + prometheus.MustRegister(GqlReceivedDataCounter) + prometheus.MustRegister(GqlMutationsCounter) + prometheus.MustRegister(GqlReceivedDataPayloadSize) + if PrometheusAdvancedMetricsEnabled { + prometheus.MustRegister(GqlReceivedDataPayloadLength) + } +} diff --git a/bbb-graphql-middleware/internal/common/SafeChannelByte.go b/bbb-graphql-middleware/internal/common/SafeChannelByte.go new file mode 100644 index 0000000000..41d8034dfe --- /dev/null +++ b/bbb-graphql-middleware/internal/common/SafeChannelByte.go @@ -0,0 +1,73 @@ +package common + +import ( + "sync" +) + +type SafeChannelByte struct { + ch chan []byte + closed bool + mux sync.Mutex + freezeFlag bool +} + +func NewSafeChannelByte(size int) *SafeChannelByte { + return &SafeChannelByte{ + ch: make(chan []byte, size), + } +} + +func (s *SafeChannelByte) Send(value []byte) bool { + s.mux.Lock() + defer s.mux.Unlock() + + if s.closed { + return false + } + s.ch <- value + return true +} + +func (s *SafeChannelByte) Receive() ([]byte, bool) { + val, ok := <-s.ch + return val, ok +} + +func (s *SafeChannelByte) ReceiveChannel() <-chan []byte { + return s.ch +} + +func (s *SafeChannelByte) Closed() bool { + s.mux.Lock() + defer s.mux.Unlock() + + return s.closed +} + +func (s *SafeChannelByte) Close() { + s.mux.Lock() + defer s.mux.Unlock() + + if !s.closed { + close(s.ch) + s.closed = true + } +} + +func (s *SafeChannelByte) Frozen() bool { + return s.freezeFlag +} + +func (s *SafeChannelByte) FreezeChannel() { + if !s.freezeFlag { + s.mux.Lock() + s.freezeFlag = true + } +} + +func (s *SafeChannelByte) UnfreezeChannel() { + if s.freezeFlag { + s.mux.Unlock() + s.freezeFlag = false + } +} diff --git a/bbb-graphql-middleware/internal/common/StreamCursorUtils.go b/bbb-graphql-middleware/internal/common/StreamCursorUtils.go index 872a13dc32..1df451356a 100644 --- a/bbb-graphql-middleware/internal/common/StreamCursorUtils.go +++ b/bbb-graphql-middleware/internal/common/StreamCursorUtils.go @@ -1,27 +1,28 @@ package common import ( + "encoding/json" "fmt" + log "github.com/sirupsen/logrus" + "hash/crc32" "regexp" "strconv" "strings" ) -func GetStreamCursorPropsFromQuery(payload map[string]interface{}, query string) (string, string, interface{}) { +func GetStreamCursorPropsFromBrowserMessage(browserMessage BrowserSubscribeMessage) (string, string, interface{}) { streamCursorField := "" streamCursorVariableName := "" var streamCursorInitialValue interface{} cursorInitialValueRePattern := regexp.MustCompile(`cursor:\s*\{\s*initial_value\s*:\s*\{\s*([^:]+):\s*([^}]+)\s*}\s*}`) - matches := cursorInitialValueRePattern.FindStringSubmatch(query) + matches := cursorInitialValueRePattern.FindStringSubmatch(browserMessage.Payload.Query) if matches != nil { streamCursorField = matches[1] if strings.HasPrefix(matches[2], "$") { streamCursorVariableName, _ = strings.CutPrefix(matches[2], "$") - if variables, okVariables := payload["variables"].(map[string]interface{}); okVariables { - if targetVariableValue, okTargetVariableValue := variables[streamCursorVariableName]; okTargetVariableValue { - streamCursorInitialValue = targetVariableValue - } + if targetVariableValue, okTargetVariableValue := browserMessage.Payload.Variables[streamCursorVariableName]; okTargetVariableValue { + streamCursorInitialValue = targetVariableValue } } else { streamCursorInitialValue = matches[2] @@ -31,9 +32,28 @@ func GetStreamCursorPropsFromQuery(payload map[string]interface{}, query string) return streamCursorField, streamCursorVariableName, streamCursorInitialValue } -func GetLastStreamCursorValueFromReceivedMessage(messageAsMap map[string]interface{}, streamCursorField string) interface{} { +func GetLastStreamCursorValueFromReceivedMessage(message []byte, streamCursorField string) interface{} { + dataChecksum := crc32.ChecksumIEEE(message) + GlobalCacheLocks.Lock(dataChecksum) + + if streamCursorValueCache, streamCursorValueCacheExists := GetStreamCursorValueCache(dataChecksum); streamCursorValueCacheExists { + //Unlock immediately once the cache was already created by other routine + GlobalCacheLocks.Unlock(dataChecksum) + return streamCursorValueCache + } else { + //It will create the cache and then Unlock (others will wait to benefit from this cache) + defer GlobalCacheLocks.Unlock(dataChecksum) + } + var lastStreamCursorValue interface{} + var messageAsMap map[string]interface{} + err := json.Unmarshal(message, &messageAsMap) + if err != nil { + log.Errorf("failed to unmarshal message: %v", err) + //return + } + if payload, okPayload := messageAsMap["payload"].(map[string]interface{}); okPayload { if data, okData := payload["data"].(map[string]interface{}); okData { //Data will have only one prop, `range` because its name is unknown @@ -52,6 +72,7 @@ func GetLastStreamCursorValueFromReceivedMessage(messageAsMap map[string]interfa } } + StoreStreamCursorValueCache(dataChecksum, lastStreamCursorValue) return lastStreamCursorValue } @@ -60,76 +81,84 @@ func PatchQueryIncludingCursorField(originalQuery string, cursorField string) st return originalQuery } - lastIndex := strings.LastIndex(originalQuery, "{") - if lastIndex == -1 { + lastIndexOfTypename := LastButOneIndex(originalQuery, "}") + if lastIndexOfTypename == -1 { return originalQuery } - // It will include the cursorField at the beginning of the list of fields + // It will include the cursorField at the end of the list of fields // It's not a problem if the field be duplicated in the list, Hasura just ignore the second occurrence - return originalQuery[:lastIndex+1] + "\n " + cursorField + originalQuery[lastIndex+1:] + return originalQuery[:lastIndexOfTypename] + " " + cursorField + "\n " + originalQuery[lastIndexOfTypename:] } -func PatchQuerySettingLastCursorValue(subscription GraphQlSubscription) interface{} { - message := subscription.Message - payload, okPayload := message["payload"].(map[string]interface{}) - - if okPayload { - if subscription.StreamCursorVariableName != "" { - /**** This stream has its cursor value set through variables ****/ - if variables, okVariables := payload["variables"].(map[string]interface{}); okVariables { - if variables[subscription.StreamCursorVariableName] != subscription.StreamCursorCurrValue { - variables[subscription.StreamCursorVariableName] = subscription.StreamCursorCurrValue - payload["variables"] = variables - message["payload"] = payload - } - } - } else { - /**** This stream has its cursor value set through inline value (not variables) ****/ - query, okQuery := payload["query"].(string) - if okQuery { - cursorInitialValueRePattern := regexp.MustCompile(`cursor:\s*\{\s*initial_value\s*:\s*\{\s*([^:]+:\s*[^}]+)\s*}\s*}`) - newValue := "" - - replaceInitialValueFunc := func(match string) string { - switch v := subscription.StreamCursorCurrValue.(type) { - case string: - newValue = v - - //Append quotes if it is missing, it will be necessary when appending to the query - if !strings.HasPrefix(v, "\"") { - newValue = "\"" + newValue - } - if !strings.HasSuffix(v, "\"") { - newValue = newValue + "\"" - } - case int: - newValue = strconv.Itoa(v) - case float32: - myFloat64 := float64(v) - newValue = strconv.FormatFloat(myFloat64, 'f', -1, 32) - case float64: - newValue = strconv.FormatFloat(v, 'f', -1, 64) - default: - newValue = "" - } - - if newValue != "" { - replacement := subscription.StreamCursorField + ": " + newValue - return fmt.Sprintf("cursor: {initial_value: {%s}}", replacement) - } else { - return match - } - } - - newQuery := cursorInitialValueRePattern.ReplaceAllStringFunc(query, replaceInitialValueFunc) - if query != newQuery { - payload["query"] = newQuery - message["payload"] = payload - } - } - } +func PatchQuerySettingLastCursorValue(subscription GraphQlSubscription) []byte { + var browserMessage BrowserSubscribeMessage + err := json.Unmarshal(subscription.Message, &browserMessage) + if err != nil { + log.Errorf("failed to unmarshal message: %v", err) + return subscription.Message } - return message + if subscription.StreamCursorVariableName != "" { + /**** This stream has its cursor value set through variables ****/ + if browserMessage.Payload.Variables[subscription.StreamCursorVariableName] == subscription.StreamCursorCurrValue { + return subscription.Message + } + browserMessage.Payload.Variables[subscription.StreamCursorVariableName] = subscription.StreamCursorCurrValue + } else { + /**** This stream has its cursor value set through inline value (not variables) ****/ + cursorInitialValueRePattern := regexp.MustCompile(`cursor:\s*\{\s*initial_value\s*:\s*\{\s*([^:]+:\s*[^}]+)\s*}\s*}`) + newValue := "" + + replaceInitialValueFunc := func(match string) string { + switch v := subscription.StreamCursorCurrValue.(type) { + case string: + newValue = v + + //Append quotes if it is missing, it will be necessary when appending to the query + if !strings.HasPrefix(v, "\"") { + newValue = "\"" + newValue + } + if !strings.HasSuffix(v, "\"") { + newValue = newValue + "\"" + } + case int: + newValue = strconv.Itoa(v) + case float32: + myFloat64 := float64(v) + newValue = strconv.FormatFloat(myFloat64, 'f', -1, 32) + case float64: + newValue = strconv.FormatFloat(v, 'f', -1, 64) + default: + newValue = "" + } + + if newValue != "" { + replacement := subscription.StreamCursorField + ": " + newValue + return fmt.Sprintf("cursor: {initial_value: {%s}}", replacement) + } else { + return match + } + } + + newQuery := cursorInitialValueRePattern.ReplaceAllStringFunc(browserMessage.Payload.Query, replaceInitialValueFunc) + if browserMessage.Payload.Query == newQuery { + return subscription.Message + } + + browserMessage.Payload.Query = newQuery + } + + newMessageJson, _ := json.Marshal(browserMessage) + + return newMessageJson +} + +func LastButOneIndex(s, substr string) int { + last := strings.LastIndex(s, substr) + if last == -1 { + return -1 + } + + return strings.LastIndex(s[:last], substr) } diff --git a/bbb-graphql-middleware/internal/common/types.go b/bbb-graphql-middleware/internal/common/types.go index d4c3c8c4cd..4ecefe6a4a 100644 --- a/bbb-graphql-middleware/internal/common/types.go +++ b/bbb-graphql-middleware/internal/common/types.go @@ -2,6 +2,8 @@ package common import ( "context" + "encoding/json" + "net/http" "sync" "nhooyr.io/websocket" @@ -19,36 +21,66 @@ const ( type GraphQlSubscription struct { Id string - Message map[string]interface{} + Message []byte Type QueryType OperationName string StreamCursorField string StreamCursorVariableName string StreamCursorCurrValue interface{} + LastReceivedData HasuraMessage LastReceivedDataChecksum uint32 JsonPatchSupported bool // indicate if client support Json Patch for this subscription LastSeenOnHasuraConnection string // id of the hasura connection that this query was active } type BrowserConnection struct { - Id string // browser connection id - SessionToken string // session token of this connection - Context context.Context // browser connection context - ActiveSubscriptions map[string]GraphQlSubscription // active subscriptions of this connection (start, but no stop) - ActiveSubscriptionsMutex sync.RWMutex // mutex to control the map usage - ConnectionInitMessage map[string]interface{} // init message received in this connection (to be used on hasura reconnect) - HasuraConnection *HasuraConnection // associated hasura connection - Disconnected bool // indicate if the connection is gone - ConnAckSentToBrowser bool // indicate if `connection_ack` msg was already sent to the browser - GraphqlActionsContext context.Context // graphql actions context - GraphqlActionsContextCancel context.CancelFunc // function to cancel the graphql actions context + Id string // browser connection id + Websocket *websocket.Conn // websocket of browser connection + SessionToken string // session token of this connection + MeetingId string // auth info provided by bbb-web + UserId string // auth info provided by bbb-web + BBBWebSessionVariables map[string]string // graphql session variables provided by akka-apps + ClientSessionUUID string // self-generated unique id for this client + Context context.Context // browser connection context + ContextCancelFunc context.CancelFunc // function to cancel the browser context (and so, the browser connection) + BrowserRequestCookies []*http.Cookie + ActiveSubscriptions map[string]GraphQlSubscription // active subscriptions of this connection (start, but no stop) + ActiveSubscriptionsMutex sync.RWMutex // mutex to control the map usage + ConnectionInitMessage []byte // init message received in this connection (to be used on hasura reconnect) + HasuraConnection *HasuraConnection // associated hasura connection + Disconnected bool // indicate if the connection is gone + ConnAckSentToBrowser bool // indicate if `connection_ack` msg was already sent to the browser + GraphqlActionsContext context.Context // graphql actions context + GraphqlActionsContextCancel context.CancelFunc // function to cancel the graphql actions context + FromBrowserToHasuraChannel *SafeChannelByte // channel to transmit messages from Browser to Hasura + FromBrowserToGqlActionsChannel *SafeChannelByte // channel to transmit messages from Browser to Graphq-Actions + FromHasuraToBrowserChannel *SafeChannelByte // channel to transmit messages from Hasura/GqlActions to Browser } type HasuraConnection struct { - Id string // hasura connection id - BrowserConn *BrowserConnection // browser connection that originated this hasura connection - Websocket *websocket.Conn // websocket used to connect to hasura - Context context.Context // hasura connection context (child of browser connection context) - ContextCancelFunc context.CancelFunc // function to cancel the hasura context (and so, the hasura connection) - FreezeMsgFromBrowserChan *SafeChannel // indicate that it's waiting for the return of mutations before closing connection + Id string // hasura connection id + BrowserConn *BrowserConnection // browser connection that originated this hasura connection + Websocket *websocket.Conn // websocket used to connect to Hasura + WebsocketCloseError *websocket.CloseError // closeError received from Hasura + Context context.Context // hasura connection context (child of browser connection context) + ContextCancelFunc context.CancelFunc // function to cancel the hasura context (and so, the hasura connection) +} + +type HasuraMessage struct { + Type string `json:"type"` + ID string `json:"id"` + Payload struct { + Data map[string]json.RawMessage `json:"data"` + } `json:"payload"` +} + +type BrowserSubscribeMessage struct { + Type string `json:"type"` + ID string `json:"id"` + Payload struct { + Extensions map[string]interface{} `json:"extensions"` + OperationName string `json:"operationName"` + Query string `json:"query"` + Variables map[string]interface{} `json:"variables"` + } `json:"payload"` } diff --git a/bbb-graphql-middleware/internal/gql_actions/client.go b/bbb-graphql-middleware/internal/gql_actions/client.go index 82ba6490e7..b666d8a441 100644 --- a/bbb-graphql-middleware/internal/gql_actions/client.go +++ b/bbb-graphql-middleware/internal/gql_actions/client.go @@ -1,37 +1,29 @@ package gql_actions import ( + "bbb-graphql-middleware/config" + "bbb-graphql-middleware/internal/common" "bytes" "encoding/json" "fmt" - "github.com/iMDT/bbb-graphql-middleware/internal/bbb_web" - "github.com/iMDT/bbb-graphql-middleware/internal/common" + "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" + "io/ioutil" "net/http" - "os" "regexp" "strings" + "time" ) -var graphqlActionsUrl = os.Getenv("BBB_GRAPHQL_MIDDLEWARE_GRAPHQL_ACTIONS_URL") +var graphqlActionsUrl = config.GetConfig().GraphqlActions.Url func GraphqlActionsClient( - browserConnection *common.BrowserConnection, - cookies []*http.Cookie, - fromBrowserToGqlActionsChannel *common.SafeChannel, - fromBrowserToHasuraChannel *common.SafeChannel, - fromHasuraToBrowserChannel *common.SafeChannel) error { + browserConnection *common.BrowserConnection) error { log := log.WithField("_routine", "GraphqlActionsClient").WithField("browserConnectionId", browserConnection.Id) log.Debug("Starting GraphqlActionsClient") defer log.Debug("Finished GraphqlActionsClient") - sessionVariables, err := bbb_web.BBBWebClient(browserConnection, cookies) - if err != nil { - log.Error("It was not able to load session variables from AuthHook", err) - return nil - } - RangeLoop: for { select { @@ -40,54 +32,78 @@ RangeLoop: case <-browserConnection.GraphqlActionsContext.Done(): log.Debug("GraphqlActionsContext cancelled!") break RangeLoop - case fromBrowserMessage := <-fromBrowserToGqlActionsChannel.ReceiveChannel(): + case fromBrowserMessage := <-browserConnection.FromBrowserToGqlActionsChannel.ReceiveChannel(): { if fromBrowserMessage == nil { continue } - var fromBrowserMessageAsMap = fromBrowserMessage.(map[string]interface{}) + var browserMessage common.BrowserSubscribeMessage + err := json.Unmarshal(fromBrowserMessage, &browserMessage) + if err != nil { + log.Errorf("failed to unmarshal message: %v", err) + continue + } - if fromBrowserMessageAsMap["type"] == "start" { - queryId := fromBrowserMessageAsMap["id"].(string) - payload := fromBrowserMessageAsMap["payload"].(map[string]interface{}) + if browserMessage.Type == "subscribe" { + var errorMessage string + var mutationFuncName string - query, okQuery := payload["query"].(string) - variables, okVariables := payload["variables"].(map[string]interface{}) - if okQuery && okVariables && strings.HasPrefix(query, "mutation") { - if funcName, inputs, err := parseGraphQLMutation(query, variables); err == nil { - if err = SendGqlActionsRequest(funcName, inputs, sessionVariables); err == nil { - //Action sent successfully, return data msg to client - browserResponseData := map[string]interface{}{ - "id": queryId, - "type": "data", - "payload": map[string]interface{}{ - "data": map[string]interface{}{ - funcName: true, - }, - }, - } - fromHasuraToBrowserChannel.Send(browserResponseData) - - //Return complete msg to client - browserResponseComplete := map[string]interface{}{ - "id": queryId, - "type": "complete", - } - fromHasuraToBrowserChannel.Send(browserResponseComplete) - - continue + if strings.HasPrefix(browserMessage.Payload.Query, "mutation") { + if funcName, inputs, err := parseGraphQLMutation(browserMessage.Payload.Query, browserMessage.Payload.Variables); err == nil { + mutationFuncName = funcName + if err = SendGqlActionsRequest(funcName, inputs, browserConnection.BBBWebSessionVariables, log); err == nil { + //Add Prometheus Metrics + common.GqlMutationsCounter.With(prometheus.Labels{"operationName": browserMessage.Payload.OperationName}).Inc() } else { + errorMessage = err.Error() log.Error("It was not able to send the request to Graphql Actions", err) } } else { + errorMessage = "It was not able to parse graphQL query" log.Error("It was not able to parse graphQL query", err) } } + + if errorMessage != "" { + //Error on sending action, return error msg to client + browserResponseData := map[string]interface{}{ + "id": browserMessage.ID, + "type": "error", + "payload": []interface{}{ + map[string]interface{}{ + "message": errorMessage, + }, + }, + } + jsonData, _ := json.Marshal(browserResponseData) + browserConnection.FromHasuraToBrowserChannel.Send(jsonData) + } else { + //Action sent successfully, return data msg to client + browserResponseData := map[string]interface{}{ + "id": browserMessage.ID, + "type": "next", + "payload": map[string]interface{}{ + "data": map[string]interface{}{ + mutationFuncName: true, + }, + }, + } + jsonData, _ := json.Marshal(browserResponseData) + browserConnection.FromHasuraToBrowserChannel.Send(jsonData) + } + + //Return complete msg to client + browserResponseComplete := map[string]interface{}{ + "id": browserMessage.ID, + "type": "complete", + } + jsonData, _ := json.Marshal(browserResponseComplete) + browserConnection.FromHasuraToBrowserChannel.Send(jsonData) } - //Something went wrong, forward message to Hasura (maybe it will be able to handle) - log.Error("It was not able to parse a Mutation, forwarding it to Hasura", fromBrowserMessage) - fromBrowserToHasuraChannel.Send(fromBrowserMessage) + + //Fallback to Hasura was disabled (keeping the code temporarily) + //fromBrowserToHasuraChannel.Send(fromBrowserMessage) } } } @@ -95,7 +111,9 @@ RangeLoop: return nil } -func SendGqlActionsRequest(funcName string, inputs map[string]interface{}, sessionVariables map[string]string) error { +func SendGqlActionsRequest(funcName string, inputs map[string]interface{}, sessionVariables map[string]string, logger *log.Entry) error { + logger = logger.WithField("funcName", funcName).WithField("inputs", inputs) + data := GqlActionsRequestBody{ Action: GqlActionsAction{ Name: funcName, @@ -113,13 +131,37 @@ func SendGqlActionsRequest(funcName string, inputs map[string]interface{}, sessi return fmt.Errorf("No Graphql Actions Url (BBB_GRAPHQL_MIDDLEWARE_GRAPHQL_ACTIONS_URL) set, aborting") } + startedAt := time.Now() + response, err := http.Post(graphqlActionsUrl, "application/json", bytes.NewBuffer(jsonData)) if err != nil { return err } defer response.Body.Close() + totalDurationMillis := time.Since(startedAt).Milliseconds() + logger = logger.WithField("duration", fmt.Sprintf("%v ms", totalDurationMillis)).WithField("statusCode", response.StatusCode) + + logger.Tracef("Executed!") + if totalDurationMillis > 100 { + logger.Infof("Took too long to execute!") + } + if response.StatusCode != 200 { + body, err := ioutil.ReadAll(response.Body) + if err != nil { + fmt.Println("Error reading response body:", err) + } + + var result map[string]interface{} + err = json.Unmarshal(body, &result) + if err == nil { + if message, ok := result["message"].(string); ok { + logger.Errorf(string(jsonData), message, err) + return fmt.Errorf("graphql actions request failed: %s", message) + } + } + return fmt.Errorf("graphql actions request failed: %s", response.Status) } @@ -162,7 +204,7 @@ func parseGraphQLMutation(query string, variables map[string]interface{}) (strin if len(paramParts) != 2 { continue // Skip invalid params } - paramName, paramValue := paramParts[0], paramParts[1] + paramName, paramValue := strings.Trim(paramParts[0], " \t"), paramParts[1] // Handle variable substitution if strings.HasPrefix(paramValue, "$") { diff --git a/bbb-graphql-middleware/internal/hasura/client.go b/bbb-graphql-middleware/internal/hasura/client.go index 9ce3991cf5..fe5236a19d 100644 --- a/bbb-graphql-middleware/internal/hasura/client.go +++ b/bbb-graphql-middleware/internal/hasura/client.go @@ -1,41 +1,30 @@ package hasura import ( + "bbb-graphql-middleware/config" + "bbb-graphql-middleware/internal/hasura/conn/reader" + "bbb-graphql-middleware/internal/hasura/conn/writer" "context" "fmt" - "github.com/iMDT/bbb-graphql-middleware/internal/hasura/conn/reader" - "github.com/iMDT/bbb-graphql-middleware/internal/hasura/conn/writer" log "github.com/sirupsen/logrus" "math" "net/http" "net/http/cookiejar" "net/url" - "os" "sync" - "github.com/iMDT/bbb-graphql-middleware/internal/common" + "bbb-graphql-middleware/internal/common" "golang.org/x/xerrors" "nhooyr.io/websocket" ) var lastHasuraConnectionId int -var hasuraEndpoint = os.Getenv("BBB_GRAPHQL_MIDDLEWARE_HASURA_WS") +var hasuraEndpoint = config.GetConfig().Hasura.Url // Hasura client connection -func HasuraClient(browserConnection *common.BrowserConnection, cookies []*http.Cookie, fromBrowserToHasuraChannel *common.SafeChannel, fromHasuraToBrowserChannel *common.SafeChannel) error { +func HasuraClient( + browserConnection *common.BrowserConnection) error { log := log.WithField("_routine", "HasuraClient").WithField("browserConnectionId", browserConnection.Id) - common.ActivitiesOverviewStarted("__HasuraConnection") - defer common.ActivitiesOverviewCompleted("__HasuraConnection") - - defer func() { - //Remove subscriptions from ActivitiesOverview here once Hasura-Reader will ignore "complete" msg for them - browserConnection.ActiveSubscriptionsMutex.RLock() - for _, subscription := range browserConnection.ActiveSubscriptions { - common.ActivitiesOverviewCompleted(string(subscription.Type) + "-" + subscription.OperationName) - common.ActivitiesOverviewCompleted("_Sum-" + string(subscription.Type)) - } - browserConnection.ActiveSubscriptionsMutex.RUnlock() - }() // Obtain id for this connection lastHasuraConnectionId++ @@ -46,7 +35,7 @@ func HasuraClient(browserConnection *common.BrowserConnection, cookies []*http.C // Add sub-protocol var dialOptions websocket.DialOptions - dialOptions.Subprotocols = append(dialOptions.Subprotocols, "graphql-ws") + dialOptions.Subprotocols = append(dialOptions.Subprotocols, "graphql-transport-ws") // Create cookie jar jar, err := cookiejar.New(nil) @@ -58,7 +47,7 @@ func HasuraClient(browserConnection *common.BrowserConnection, cookies []*http.C return xerrors.Errorf("failed to parse url: %w", err) } parsedURL.Scheme = "http" - jar.SetCookies(parsedURL, cookies) + jar.SetCookies(parsedURL, browserConnection.BrowserRequestCookies) hc := &http.Client{ Jar: jar, } @@ -72,32 +61,37 @@ func HasuraClient(browserConnection *common.BrowserConnection, cookies []*http.C defer hasuraConnectionContextCancel() var thisConnection = common.HasuraConnection{ - Id: hasuraConnectionId, - BrowserConn: browserConnection, - Context: hasuraConnectionContext, - ContextCancelFunc: hasuraConnectionContextCancel, - FreezeMsgFromBrowserChan: common.NewSafeChannel(1), + Id: hasuraConnectionId, + BrowserConn: browserConnection, + Context: hasuraConnectionContext, + ContextCancelFunc: hasuraConnectionContextCancel, } browserConnection.HasuraConnection = &thisConnection defer func() { + //When Hasura sends an CloseError, it will forward the error to the browser and close the connection + if thisConnection.WebsocketCloseError != nil { + browserConnection.Websocket.Close(thisConnection.WebsocketCloseError.Code, thisConnection.WebsocketCloseError.Reason) + browserConnection.ContextCancelFunc() + } + browserConnection.HasuraConnection = nil //It's necessary to freeze the channel to avoid client trying to start subscriptions before Hasura connection is initialised //It will unfreeze after `connection_ack` is sent by Hasura - fromBrowserToHasuraChannel.FreezeChannel() + browserConnection.FromBrowserToHasuraChannel.FreezeChannel() }() // Make the connection - c, _, err := websocket.Dial(hasuraConnectionContext, hasuraEndpoint, &dialOptions) + hasuraWsConn, _, err := websocket.Dial(hasuraConnectionContext, hasuraEndpoint, &dialOptions) if err != nil { return xerrors.Errorf("error connecting to hasura: %v", err) } - defer c.Close(websocket.StatusInternalError, "the sky is falling") + defer hasuraWsConn.Close(websocket.StatusInternalError, "the sky is falling") - c.SetReadLimit(math.MaxInt64 - 1) + hasuraWsConn.SetReadLimit(math.MaxInt64 - 1) - thisConnection.Websocket = c + thisConnection.Websocket = hasuraWsConn // Log the connection success log.Debugf("connected with Hasura") @@ -109,10 +103,10 @@ func HasuraClient(browserConnection *common.BrowserConnection, cookies []*http.C // Start routines // reads from browser, writes to hasura - go writer.HasuraConnectionWriter(&thisConnection, fromBrowserToHasuraChannel, &wg, browserConnection.ConnectionInitMessage) + go writer.HasuraConnectionWriter(&thisConnection, &wg, browserConnection.ConnectionInitMessage) // reads from hasura, writes to browser - go reader.HasuraConnectionReader(&thisConnection, fromHasuraToBrowserChannel, fromBrowserToHasuraChannel, &wg) + go reader.HasuraConnectionReader(&thisConnection, &wg) // Wait wg.Wait() diff --git a/bbb-graphql-middleware/internal/hasura/conn/reader/reader.go b/bbb-graphql-middleware/internal/hasura/conn/reader/reader.go index a0fd8ed4e7..6e8ff0ec15 100644 --- a/bbb-graphql-middleware/internal/hasura/conn/reader/reader.go +++ b/bbb-graphql-middleware/internal/hasura/conn/reader/reader.go @@ -1,21 +1,22 @@ package reader import ( + "bbb-graphql-middleware/internal/common" + "bbb-graphql-middleware/internal/hasura/retransmiter" + "bbb-graphql-middleware/internal/msgpatch" + "bytes" "context" "encoding/json" "errors" - "fmt" - "github.com/iMDT/bbb-graphql-middleware/internal/common" - "github.com/iMDT/bbb-graphql-middleware/internal/hasura/retransmiter" - "github.com/iMDT/bbb-graphql-middleware/internal/msgpatch" + "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" "hash/crc32" - "nhooyr.io/websocket/wsjson" + "nhooyr.io/websocket" "sync" ) // HasuraConnectionReader consumes messages from Hasura connection and add send to the browser channel -func HasuraConnectionReader(hc *common.HasuraConnection, fromHasuraToBrowserChannel *common.SafeChannel, fromBrowserToHasuraChannel *common.SafeChannel, wg *sync.WaitGroup) { +func HasuraConnectionReader(hc *common.HasuraConnection, wg *sync.WaitGroup) { log := log.WithField("_routine", "HasuraConnectionReader").WithField("browserConnectionId", hc.BrowserConn.Id).WithField("hasuraConnectionId", hc.Id) defer log.Debugf("finished") log.Debugf("starting") @@ -24,121 +25,155 @@ func HasuraConnectionReader(hc *common.HasuraConnection, fromHasuraToBrowserChan defer hc.ContextCancelFunc() for { - // Read a message from hasura - var message interface{} - err := wsjson.Read(hc.Context, hc.Websocket, &message) + messageType, message, err := hc.Websocket.Read(hc.Context) + var closeError *websocket.CloseError + if err != nil { if errors.Is(err, context.Canceled) { log.Debugf("Closing Hasura ws connection as Context was cancelled!") + } else if errors.As(err, &closeError) { + hc.WebsocketCloseError = closeError + log.Debug("WebSocket connection closed: status = %v, reason = %s", closeError.Code, closeError.Reason) + //TODO check if it should send {"type":"connection_error","payload":"Authentication hook unauthorized this request"} } else { + if websocket.CloseStatus(err) == -1 { + //It doesn't have a CloseError, it will reconnect do Hasura + } else { + //In case Hasura sent an CloseError, it will forward it to browser and disconnect + hc.WebsocketCloseError = &websocket.CloseError{ + Code: websocket.CloseStatus(err), + Reason: "Graphql connection closed with error" + err.Error(), + } + } + log.Debugf("Error reading message from Hasura: %v", err) } return } - log.Tracef("received from hasura: %v", message) + if messageType != websocket.MessageText { + log.Warnf("received non-text message: %v", messageType) + continue + } - handleMessageReceivedFromHasura(hc, fromHasuraToBrowserChannel, fromBrowserToHasuraChannel, message) + log.Tracef("received from hasura: %s", string(message)) + + handleMessageReceivedFromHasura(hc, message) } } -func handleMessageReceivedFromHasura(hc *common.HasuraConnection, fromHasuraToBrowserChannel *common.SafeChannel, fromBrowserToHasuraChannel *common.SafeChannel, message interface{}) { - var messageMap = message.(map[string]interface{}) +var QueryIdPlaceholderInBytes = []byte("--------------QUERY-ID--------------") //36 chars - if messageMap != nil { - var messageType = messageMap["type"] - var queryId, _ = messageMap["id"].(string) +func handleMessageReceivedFromHasura(hc *common.HasuraConnection, message []byte) { + type HasuraMessageInfo struct { + Type string `json:"type"` + ID string `json:"id"` + } + var hasuraMessageInfo HasuraMessageInfo + err := json.Unmarshal(message, &hasuraMessageInfo) + if err != nil { + log.Errorf("failed to unmarshal message: %v", err) + return + } - //Check if subscription is still active! - if queryId != "" { - hc.BrowserConn.ActiveSubscriptionsMutex.RLock() - subscription, ok := hc.BrowserConn.ActiveSubscriptions[queryId] - hc.BrowserConn.ActiveSubscriptionsMutex.RUnlock() - if !ok { - log.Debugf("Subscription with Id %s doesn't exist anymore, skipping response.", queryId) + queryIdReplacementApplied := false + queryIdInBytes := []byte(hasuraMessageInfo.ID) + + //Check if subscription is still active! + if hasuraMessageInfo.ID != "" { + hc.BrowserConn.ActiveSubscriptionsMutex.RLock() + subscription, ok := hc.BrowserConn.ActiveSubscriptions[hasuraMessageInfo.ID] + hc.BrowserConn.ActiveSubscriptionsMutex.RUnlock() + if !ok { + log.Debugf("Subscription with Id %s doesn't exist anymore, skipping response.", hasuraMessageInfo.ID) + return + } + + //When Hasura send msg type "complete", this query is finished + if hasuraMessageInfo.Type == "complete" { + handleCompleteMessage(hc, hasuraMessageInfo.ID) + } + + if hasuraMessageInfo.Type == "next" { + common.GqlReceivedDataCounter. + With(prometheus.Labels{ + "type": string(subscription.Type), + "operationName": subscription.OperationName}). + Inc() + } + + if hasuraMessageInfo.Type == "next" && + subscription.Type == common.Subscription { + + //Remove queryId from message + message = bytes.Replace(message, queryIdInBytes, QueryIdPlaceholderInBytes, 1) + queryIdReplacementApplied = true + + isDifferentFromPreviousMessage := handleSubscriptionMessage(hc, &message, subscription, hasuraMessageInfo.ID) + + //Stop processing case it is the same message (probably is a reconnection with Hasura) + if !isDifferentFromPreviousMessage { return } - - //When Hasura send msg type "complete", this query is finished - if messageType == "complete" { - handleCompleteMessage(hc, queryId) - common.ActivitiesOverviewCompleted(string(subscription.Type) + "-" + subscription.OperationName) - common.ActivitiesOverviewCompleted("_Sum-" + string(subscription.Type)) - } - - if messageType == "data" { - common.ActivitiesOverviewDataReceived(string(subscription.Type) + "-" + subscription.OperationName) - } - - if messageType == "data" && - subscription.Type == common.Subscription { - hasNoPreviousOccurrence := handleSubscriptionMessage(hc, messageMap, subscription, queryId) - - if !hasNoPreviousOccurrence { - return - } - } - - //Set last cursor value for stream - if subscription.Type == common.Streaming { - handleStreamingMessage(hc, messageMap, subscription, queryId) - } } - // Retransmit the subscription start commands when hasura confirms the connection - // this is useful in case of a connection invalidation - if messageType == "connection_ack" { - handleConnectionAckMessage(hc, messageMap, fromHasuraToBrowserChannel, fromBrowserToHasuraChannel) - } else { - // Forward the message to browser - fromHasuraToBrowserChannel.Send(messageMap) + //Set last cursor value for stream + if subscription.Type == common.Streaming { + //Remove queryId from message + messageWithoutId := bytes.Replace(message, queryIdInBytes, QueryIdPlaceholderInBytes, 1) + + handleStreamingMessage(hc, messageWithoutId, subscription, hasuraMessageInfo.ID) } } + + // Retransmit the subscription start commands when hasura confirms the connection + // this is useful in case of a connection invalidation + if hasuraMessageInfo.Type == "connection_ack" { + handleConnectionAckMessage(hc, message) + } else { + if queryIdReplacementApplied { + message = bytes.Replace(message, QueryIdPlaceholderInBytes, queryIdInBytes, 1) + } + + // Forward the message to browser + hc.BrowserConn.FromHasuraToBrowserChannel.Send(message) + } } -func handleSubscriptionMessage(hc *common.HasuraConnection, messageMap map[string]interface{}, subscription common.GraphQlSubscription, queryId string) bool { - if payload, okPayload := messageMap["payload"].(map[string]interface{}); okPayload { - if data, okData := payload["data"].(map[string]interface{}); okData { - for dataKey, dataItem := range data { - if currentDataProp, okCurrentDataProp := dataItem.([]interface{}); okCurrentDataProp { - if dataAsJson, err := json.Marshal(currentDataProp); err == nil { - if common.ActivitiesOverviewEnabled { - dataSize := len(string(dataAsJson)) - dataCount := len(currentDataProp) - common.ActivitiesOverviewDataSize(string(subscription.Type)+"-"+subscription.OperationName, int64(dataSize), int64(dataCount)) - } +func handleSubscriptionMessage(hc *common.HasuraConnection, message *[]byte, subscription common.GraphQlSubscription, queryId string) bool { + dataChecksum, messageDataKey, messageData := getHasuraMessage(*message, subscription) - //Check whether ReceivedData is different from the LastReceivedData - //Otherwise stop forwarding this message - dataChecksum := crc32.ChecksumIEEE(dataAsJson) - if subscription.LastReceivedDataChecksum == dataChecksum { - return false - } + //Check whether ReceivedData is different from the LastReceivedData + //Otherwise stop forwarding this message + if subscription.LastReceivedDataChecksum == dataChecksum { + return false + } - lastDataChecksumWas := subscription.LastReceivedDataChecksum - cacheKey := fmt.Sprintf("%s-%s-%v-%v", string(subscription.Type), subscription.OperationName, subscription.LastReceivedDataChecksum, dataChecksum) + lastDataChecksumWas := subscription.LastReceivedDataChecksum + lastReceivedDataWas := subscription.LastReceivedData + cacheKey := mergeUint32(subscription.LastReceivedDataChecksum, dataChecksum) - //Store LastReceivedData Checksum - subscription.LastReceivedDataChecksum = dataChecksum - hc.BrowserConn.ActiveSubscriptionsMutex.Lock() - hc.BrowserConn.ActiveSubscriptions[queryId] = subscription - hc.BrowserConn.ActiveSubscriptionsMutex.Unlock() + //Store LastReceivedData Checksum + subscription.LastReceivedData = messageData + subscription.LastReceivedDataChecksum = dataChecksum + hc.BrowserConn.ActiveSubscriptionsMutex.Lock() + hc.BrowserConn.ActiveSubscriptions[queryId] = subscription + hc.BrowserConn.ActiveSubscriptionsMutex.Unlock() - //Apply msg patch when it supports it - if subscription.JsonPatchSupported { - msgpatch.PatchMessage(&messageMap, queryId, dataKey, dataAsJson, hc.BrowserConn, cacheKey, lastDataChecksumWas, dataChecksum) - } - } - } - } - } + //Apply msg patch when it supports it + if subscription.JsonPatchSupported { + *message = msgpatch.GetPatchedMessage(*message, messageDataKey, lastReceivedDataWas, messageData, cacheKey, lastDataChecksumWas, dataChecksum) } return true } -func handleStreamingMessage(hc *common.HasuraConnection, messageMap map[string]interface{}, subscription common.GraphQlSubscription, queryId string) { - lastCursor := common.GetLastStreamCursorValueFromReceivedMessage(messageMap, subscription.StreamCursorField) +func mergeUint32(a, b uint32) uint32 { + return (a << 16) | (b >> 16) +} + +func handleStreamingMessage(hc *common.HasuraConnection, message []byte, subscription common.GraphQlSubscription, queryId string) { + lastCursor := common.GetLastStreamCursorValueFromReceivedMessage(message, subscription.StreamCursorField) if lastCursor != nil && subscription.StreamCursorCurrValue != lastCursor { subscription.StreamCursorCurrValue = lastCursor @@ -157,16 +192,67 @@ func handleCompleteMessage(hc *common.HasuraConnection, queryId string) { log.Debugf("%s (%s) with Id %s finished by Hasura.", queryType, operationName, queryId) } -func handleConnectionAckMessage(hc *common.HasuraConnection, messageMap map[string]interface{}, fromHasuraToBrowserChannel *common.SafeChannel, fromBrowserToHasuraChannel *common.SafeChannel) { +func handleConnectionAckMessage(hc *common.HasuraConnection, message []byte) { log.Debugf("Received connection_ack") //Hasura connection was initialized, now it's able to send new messages to Hasura - fromBrowserToHasuraChannel.UnfreezeChannel() + hc.BrowserConn.FromBrowserToHasuraChannel.UnfreezeChannel() //Avoid to send `connection_ack` to the browser when it's a reconnection if hc.BrowserConn.ConnAckSentToBrowser == false { - fromHasuraToBrowserChannel.Send(messageMap) + hc.BrowserConn.FromHasuraToBrowserChannel.Send(message) hc.BrowserConn.ConnAckSentToBrowser = true } - go retransmiter.RetransmitSubscriptionStartMessages(hc, fromBrowserToHasuraChannel) + go retransmiter.RetransmitSubscriptionStartMessages(hc) +} + +func getHasuraMessage(message []byte, subscription common.GraphQlSubscription) (uint32, string, common.HasuraMessage) { + dataChecksum := crc32.ChecksumIEEE(message) + + common.GlobalCacheLocks.Lock(dataChecksum) + defer common.GlobalCacheLocks.Unlock(dataChecksum) + + dataKey, hasuraMessage, dataMapExists := common.GetHasuraMessageCache(dataChecksum) + if dataMapExists { + return dataChecksum, dataKey, hasuraMessage + } + + err := json.Unmarshal(message, &hasuraMessage) + if err != nil { + log.Fatalf("Error unmarshalling JSON: %v", err) + } + + for key := range hasuraMessage.Payload.Data { + dataKey = key + break + } + + common.StoreHasuraMessageCache(dataChecksum, dataKey, hasuraMessage) + + //Add Prometheus metrics only once for each dataChecksum + dataSize := len(string(message)) + common.GqlReceivedDataPayloadSize. + With(prometheus.Labels{ + "type": string(subscription.Type), + "operationName": subscription.OperationName}). + Observe(float64(dataSize)) + + if common.PrometheusAdvancedMetricsEnabled { + // Decode the JSON array into raw messages + var rawMessages []json.RawMessage + err := json.Unmarshal(hasuraMessage.Payload.Data[dataKey], &rawMessages) + if err == nil { + // Get the length of the array + dataLength := len(rawMessages) + + common.GqlReceivedDataPayloadLength. + With(prometheus.Labels{ + "type": string(subscription.Type), + "operationName": subscription.OperationName}). + Observe(float64(dataLength)) + + } + } + + return dataChecksum, dataKey, hasuraMessage } diff --git a/bbb-graphql-middleware/internal/hasura/conn/writer/writer.go b/bbb-graphql-middleware/internal/hasura/conn/writer/writer.go index 3c073c2283..98dcf885da 100644 --- a/bbb-graphql-middleware/internal/hasura/conn/writer/writer.go +++ b/bbb-graphql-middleware/internal/hasura/conn/writer/writer.go @@ -1,20 +1,35 @@ package writer import ( + "bbb-graphql-middleware/config" + "bbb-graphql-middleware/internal/common" "context" + "encoding/json" "errors" - "github.com/iMDT/bbb-graphql-middleware/internal/common" - "github.com/iMDT/bbb-graphql-middleware/internal/msgpatch" + "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" - "nhooyr.io/websocket/wsjson" - "os" + "nhooyr.io/websocket" "strings" "sync" ) +var allowedSubscriptions []string +var deniedSubscriptions []string +var jsonPatchDisabled = config.GetConfig().Server.JsonPatchDisabled + +func init() { + if config.GetConfig().Server.SubscriptionAllowedList != "" { + allowedSubscriptions = strings.Split(config.GetConfig().Server.SubscriptionAllowedList, ",") + } + + if config.GetConfig().Server.SubscriptionsDeniedList != "" { + deniedSubscriptions = strings.Split(config.GetConfig().Server.SubscriptionsDeniedList, ",") + } +} + // HasuraConnectionWriter // process messages (middleware to hasura) -func HasuraConnectionWriter(hc *common.HasuraConnection, fromBrowserToHasuraChannel *common.SafeChannel, wg *sync.WaitGroup, initMessage map[string]interface{}) { +func HasuraConnectionWriter(hc *common.HasuraConnection, wg *sync.WaitGroup, initMessage []byte) { log := log.WithField("_routine", "HasuraConnectionWriter") browserConnection := hc.BrowserConn @@ -27,13 +42,16 @@ func HasuraConnectionWriter(hc *common.HasuraConnection, fromBrowserToHasuraChan //Send authentication (init) message at first //It will not use the channel (fromBrowserToHasuraChannel) because this msg must bypass ChannelFreeze - if initMessage != nil { - log.Infof("it's a reconnection, injecting authentication (init) message") - err := wsjson.Write(hc.Context, hc.Websocket, initMessage) - if err != nil { - log.Errorf("error on write authentication (init) message (we're disconnected from hasura): %v", err) - return - } + if initMessage == nil { + log.Errorf("it can't start Hasura Connection because initMessage is null") + return + } + + //Send init connection message to Hasura to start + err := hc.Websocket.Write(hc.Context, websocket.MessageText, initMessage) + if err != nil { + log.Errorf("error on write authentication (init) message (we're disconnected from hasura): %v", err) + return } RangeLoop: @@ -41,22 +59,23 @@ RangeLoop: select { case <-hc.Context.Done(): break RangeLoop - case <-hc.FreezeMsgFromBrowserChan.ReceiveChannel(): - if !fromBrowserToHasuraChannel.Frozen() { - log.Debug("freezing channel fromBrowserToHasuraChannel") - //Freeze channel once it's about to close Hasura connection - fromBrowserToHasuraChannel.FreezeChannel() - } - case fromBrowserMessage := <-fromBrowserToHasuraChannel.ReceiveChannel(): + case fromBrowserMessage := <-hc.BrowserConn.FromBrowserToHasuraChannel.ReceiveChannel(): { if fromBrowserMessage == nil { continue } - var fromBrowserMessageAsMap = fromBrowserMessage.(map[string]interface{}) + //var fromBrowserMessageAsMap = fromBrowserMessage.(map[string]interface{}) - if fromBrowserMessageAsMap["type"] == "start" { - var queryId = fromBrowserMessageAsMap["id"].(string) + var browserMessage common.BrowserSubscribeMessage + err := json.Unmarshal(fromBrowserMessage, &browserMessage) + if err != nil { + log.Errorf("failed to unmarshal message: %v", err) + return + } + + if browserMessage.Type == "subscribe" { + var queryId = browserMessage.ID //Identify type based on query string messageType := common.Query @@ -64,26 +83,38 @@ RangeLoop: streamCursorField := "" streamCursorVariableName := "" var streamCursorInitialValue interface{} - payload := fromBrowserMessageAsMap["payload"].(map[string]interface{}) - operationName, ok := payload["operationName"].(string) - query, ok := payload["query"].(string) - if ok { + query := browserMessage.Payload.Query + if query != "" { if strings.HasPrefix(query, "subscription") { - //Validate if subscription is allowed - if allowedSubscriptions := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_ALLOWED_SUBSCRIPTIONS"); allowedSubscriptions != "" { - allowedSubscriptionsSlice := strings.Split(allowedSubscriptions, ",") + if len(allowedSubscriptions) > 0 { subscriptionAllowed := false - for _, s := range allowedSubscriptionsSlice { - if s == operationName { + for _, s := range allowedSubscriptions { + if s == browserMessage.Payload.OperationName { subscriptionAllowed = true break } } if !subscriptionAllowed { - log.Infof("Subscription %s not allowed!", operationName) + log.Infof("Subscription %s not allowed!", browserMessage.Payload.OperationName) + continue + } + } + + //Validate if subscription is allowed + if len(deniedSubscriptions) > 0 { + subscriptionAllowed := true + for _, s := range deniedSubscriptions { + if s == browserMessage.Payload.OperationName { + subscriptionAllowed = false + break + } + } + + if !subscriptionAllowed { + log.Infof("Subscription %s not allowed!", browserMessage.Payload.OperationName) continue } } @@ -95,18 +126,22 @@ RangeLoop: browserConnection.ActiveSubscriptionsMutex.RUnlock() if queryIdExists { lastReceivedDataChecksum = existingSubscriptionData.LastReceivedDataChecksum + streamCursorField = existingSubscriptionData.StreamCursorField + streamCursorVariableName = existingSubscriptionData.StreamCursorVariableName + streamCursorInitialValue = existingSubscriptionData.StreamCursorCurrValue } if strings.Contains(query, "_stream(") && strings.Contains(query, "cursor: {") { messageType = common.Streaming - if !queryIdExists { - streamCursorField, streamCursorVariableName, streamCursorInitialValue = common.GetStreamCursorPropsFromQuery(payload, query) + streamCursorField, streamCursorVariableName, streamCursorInitialValue = common.GetStreamCursorPropsFromBrowserMessage(browserMessage) //It's necessary to assure the cursor field will return in the result of the query //To be able to store the last received cursor value - payload["query"] = common.PatchQueryIncludingCursorField(query, streamCursorField) - fromBrowserMessageAsMap["payload"] = payload + browserMessage.Payload.Query = common.PatchQueryIncludingCursorField(query, streamCursorField) + + newMessageJson, _ := json.Marshal(browserMessage) + fromBrowserMessage = newMessageJson } } @@ -123,18 +158,15 @@ RangeLoop: //Identify if the client that requested this subscription expects to receive json-patch //Client append `Patched_` to the query operationName to indicate that it supports jsonPatchSupported := false - if ok && strings.HasPrefix(operationName, "Patched_") { + if !jsonPatchDisabled && strings.HasPrefix(browserMessage.Payload.OperationName, "Patched_") { jsonPatchSupported = true } - if jsonPatchDisabled := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_JSON_PATCH_DISABLED"); jsonPatchDisabled != "" { - jsonPatchSupported = false - } browserConnection.ActiveSubscriptionsMutex.Lock() browserConnection.ActiveSubscriptions[queryId] = common.GraphQlSubscription{ Id: queryId, - Message: fromBrowserMessageAsMap, - OperationName: operationName, + Message: fromBrowserMessage, + OperationName: browserMessage.Payload.OperationName, StreamCursorField: streamCursorField, StreamCursorVariableName: streamCursorVariableName, StreamCursorCurrValue: streamCursorInitialValue, @@ -146,42 +178,41 @@ RangeLoop: // log.Tracef("Current queries: %v", browserConnection.ActiveSubscriptions) browserConnection.ActiveSubscriptionsMutex.Unlock() - common.ActivitiesOverviewStarted(string(messageType) + "-" + operationName) - common.ActivitiesOverviewStarted("_Sum-" + string(messageType)) + //Add Prometheus Metrics + common.GqlSubscribeCounter. + With(prometheus.Labels{ + "type": string(messageType), + "operationName": browserMessage.Payload.OperationName}). + Inc() //Dump of all subscriptions for analysis purpose - //saveItToFile(fmt.Sprintf("%02s-%s-%s", queryId, string(messageType), operationName), fromBrowserMessageAsMap) - //saveItToFile(fmt.Sprintf("%s-%s-%02s", string(messageType), operationName, queryId), fromBrowserMessageAsMap) + //queryCounter++ + //saveItToFile(fmt.Sprintf("%02d-%s-%s", queryCounter, string(messageType), browserMessage.Payload.OperationName), fromBrowserMessage) + //saveItToFile(fmt.Sprintf("%s-%s-%02s", string(messageType), operationName, queryId), fromBrowserMessage) } - if fromBrowserMessageAsMap["type"] == "stop" { - var queryId = fromBrowserMessageAsMap["id"].(string) + if browserMessage.Type == "complete" { browserConnection.ActiveSubscriptionsMutex.RLock() - jsonPatchSupported := browserConnection.ActiveSubscriptions[queryId].JsonPatchSupported - //Remove subscriptions from ActivitiesOverview here once Hasura-Reader will ignore "complete" msg for them - common.ActivitiesOverviewCompleted(string(browserConnection.ActiveSubscriptions[queryId].Type) + "-" + browserConnection.ActiveSubscriptions[queryId].OperationName) - common.ActivitiesOverviewCompleted("_Sum-" + string(browserConnection.ActiveSubscriptions[queryId].Type)) browserConnection.ActiveSubscriptionsMutex.RUnlock() - if jsonPatchSupported { - msgpatch.RemoveConnSubscriptionCacheFile(browserConnection, queryId) - } browserConnection.ActiveSubscriptionsMutex.Lock() - delete(browserConnection.ActiveSubscriptions, queryId) + delete(browserConnection.ActiveSubscriptions, browserMessage.ID) // log.Tracef("Current queries: %v", browserConnection.ActiveSubscriptions) browserConnection.ActiveSubscriptionsMutex.Unlock() } - if fromBrowserMessageAsMap["type"] == "connection_init" { - browserConnection.ConnectionInitMessage = fromBrowserMessageAsMap + if browserMessage.Type == "connection_init" { + //browserConnection.ConnectionInitMessage = fromBrowserMessageAsMap + //Skip message once it is handled by ConnInitHandler already + continue } - log.Tracef("sending to hasura: %v", fromBrowserMessageAsMap) - err := wsjson.Write(hc.Context, hc.Websocket, fromBrowserMessageAsMap) - if err != nil { - if !errors.Is(err, context.Canceled) { - log.Errorf("error on write (we're disconnected from hasura): %v", err) + log.Tracef("sending to hasura: %s", string(fromBrowserMessage)) + errWrite := hc.Websocket.Write(hc.Context, websocket.MessageText, fromBrowserMessage) + if errWrite != nil { + if !errors.Is(errWrite, context.Canceled) { + log.Errorf("error on write (we're disconnected from hasura): %v", errWrite) } return } @@ -191,9 +222,11 @@ RangeLoop: } // -//func saveItToFile(filename string, contentInBytes interface{}) { +//var queryCounter = 0 +// +//func saveItToFile(filename string, contentInBytes []byte) { // filePath := fmt.Sprintf("/tmp/%s.txt", filename) -// message, err := json.Marshal(contentInBytes) +// //message, err := json.Marshal(contentInBytes) // // fmt.Printf("Saving %s\n", filePath) // @@ -203,7 +236,7 @@ RangeLoop: // } // defer file.Close() // -// _, err = file.Write(message) +// _, err = file.Write(contentInBytes) // if err != nil { // panic(err) // } diff --git a/bbb-graphql-middleware/internal/hasura/retransmiter/retransmiter.go b/bbb-graphql-middleware/internal/hasura/retransmiter/retransmiter.go index 221ea5ad47..27809be6af 100644 --- a/bbb-graphql-middleware/internal/hasura/retransmiter/retransmiter.go +++ b/bbb-graphql-middleware/internal/hasura/retransmiter/retransmiter.go @@ -1,31 +1,44 @@ package retransmiter import ( - "github.com/iMDT/bbb-graphql-middleware/internal/common" + "bbb-graphql-middleware/internal/common" log "github.com/sirupsen/logrus" ) -func RetransmitSubscriptionStartMessages(hc *common.HasuraConnection, fromBrowserToHasuraChannel *common.SafeChannel) { +func RetransmitSubscriptionStartMessages(hc *common.HasuraConnection) { log := log.WithField("_routine", "RetransmitSubscriptionStartMessages").WithField("browserConnectionId", hc.BrowserConn.Id).WithField("hasuraConnectionId", hc.Id) hc.BrowserConn.ActiveSubscriptionsMutex.RLock() - for _, subscription := range hc.BrowserConn.ActiveSubscriptions { + defer hc.BrowserConn.ActiveSubscriptionsMutex.RUnlock() + userCurrentlyInMeeting := false + if hasuraRole, exists := hc.BrowserConn.BBBWebSessionVariables["x-hasura-role"]; exists { + userCurrentlyInMeeting = hasuraRole == "bbb_client" + } + + for _, subscription := range hc.BrowserConn.ActiveSubscriptions { //Not retransmitting Mutations if subscription.Type == common.Mutation { continue } - if subscription.LastSeenOnHasuraConnection != hc.Id { + //When user left the meeting, Retransmit only Presence Manager subscriptions + if !userCurrentlyInMeeting && + subscription.OperationName != "getUserInfo" && + subscription.OperationName != "getUserCurrent" { + log.Debugf("Skipping retransmit %s because the user is offline", subscription.OperationName) + continue + } - log.Tracef("retransmiting subscription start: %v", subscription.Message) + if subscription.LastSeenOnHasuraConnection != hc.Id { + log.Tracef("retransmiting subscription start: %v", string(subscription.Message)) if subscription.Type == common.Streaming && subscription.StreamCursorCurrValue != nil { - fromBrowserToHasuraChannel.Send(common.PatchQuerySettingLastCursorValue(subscription)) + hc.BrowserConn.FromBrowserToHasuraChannel.Send(common.PatchQuerySettingLastCursorValue(subscription)) } else { - fromBrowserToHasuraChannel.Send(subscription.Message) + hc.BrowserConn.FromBrowserToHasuraChannel.Send(subscription.Message) } } } - hc.BrowserConn.ActiveSubscriptionsMutex.RUnlock() + } diff --git a/bbb-graphql-middleware/internal/msgpatch/jsonpatch.go b/bbb-graphql-middleware/internal/msgpatch/jsonpatch.go index ed07f0b748..3f47ec93cc 100644 --- a/bbb-graphql-middleware/internal/msgpatch/jsonpatch.go +++ b/bbb-graphql-middleware/internal/msgpatch/jsonpatch.go @@ -1,178 +1,85 @@ package msgpatch import ( + "bbb-graphql-middleware/internal/common" "encoding/json" - "github.com/iMDT/bbb-graphql-middleware/internal/common" "github.com/mattbaird/jsonpatch" log "github.com/sirupsen/logrus" - "io/ioutil" - "os" - "path/filepath" - "strings" + "strconv" ) -var cacheDir = os.TempDir() + "/graphql-middleware-cache/" var minLengthToPatch = 250 //250 chars var minShrinkToUsePatch = 0.5 //50% percent -func getConnPath(connectionId string) string { - return cacheDir + connectionId -} - -func getSubscriptionCacheDirPath( - bConn *common.BrowserConnection, - subscriptionId string, - createIfNotExists bool) (string, error) { - //Using SessionToken as path to reinforce security (once connectionId repeats on restart of middleware) - connectionPatchCachePath := getConnPath(bConn.Id) + "/" + bConn.SessionToken + "/" - subscriptionCacheDirPath := connectionPatchCachePath + subscriptionId + "/" - _, err := os.Stat(subscriptionCacheDirPath) - if err != nil { - if os.IsNotExist(err) && createIfNotExists { - err = os.MkdirAll(subscriptionCacheDirPath, 0755) - if err != nil { - log.Errorf("Error on create cache directory: %v", err) - return subscriptionCacheDirPath, nil - } - } else { - return "", err - } - } - - return subscriptionCacheDirPath, nil -} - -func RemoveConnCacheDir(connectionId string) { - err := os.RemoveAll(getConnPath(connectionId)) - if err != nil { - if !os.IsNotExist(err) { - log.Errorf("Error while removing CLI patch cache directory: %v", err) - } - return - } - - log.Debugf("Directory of patch caches removed successfully for client %s.", connectionId) -} - -func RemoveConnSubscriptionCacheFile(bConn *common.BrowserConnection, subscriptionId string) { - subsCacheDirPath, err := getSubscriptionCacheDirPath(bConn, subscriptionId, false) - if err == nil { - err = os.RemoveAll(subsCacheDirPath) - if err != nil { - if !os.IsNotExist(err) { - log.Errorf("Error while removing CLI subscription patch cache directory: %v", err) - } - return - } - - log.Debugf("Directory of patch caches removed successfully for client %s, subscription %s.", bConn.Id, subscriptionId) - } -} - -func ClearAllCaches() { - info, err := os.Stat(cacheDir) - if err == nil && info.IsDir() { - filepath.Walk(cacheDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - log.Debugf("Cache dir was removed previously (probably user disconnected): %q: %v\n", path, err) - return err - } - - if info.IsDir() && path != cacheDir { - os.RemoveAll(path) - } - return nil - }) - } -} - -func fileExists(filename string) bool { - _, err := os.Stat(filename) - return !os.IsNotExist(err) -} - -func PatchMessage( - receivedMessage *map[string]interface{}, - queryId string, +func GetPatchedMessage( + receivedMessage []byte, dataKey string, - dataAsJson []byte, - bConn *common.BrowserConnection, - cacheKey string, + lastHasuraMessage common.HasuraMessage, + hasuraMessage common.HasuraMessage, + cacheKey uint32, lastDataChecksum uint32, - currDataChecksum uint32) { + currDataChecksum uint32) []byte { if lastDataChecksum != 0 { - common.JsonPatchBenchmarkingStarted(cacheKey) - defer common.JsonPatchBenchmarkingCompleted(cacheKey) + common.JsonPatchBenchmarkingStarted(strconv.Itoa(int(cacheKey))) + defer common.JsonPatchBenchmarkingCompleted(strconv.Itoa(int(cacheKey))) } - //Avoid other routines from processing the same JsonPatch + //Lock to avoid other routines from processing the same message common.GlobalCacheLocks.Lock(cacheKey) - jsonDiffPatch, jsonDiffPatchExists := common.GetJsonPatchCache(cacheKey) - if jsonDiffPatchExists { + if patchedMessageCache, patchedMessageCacheExists := common.GetPatchedMessageCache(cacheKey); patchedMessageCacheExists { //Unlock immediately once the cache was already created by other routine common.GlobalCacheLocks.Unlock(cacheKey) + return patchedMessageCache } else { //It will create the cache and then Unlock (others will wait to benefit from this cache) defer common.GlobalCacheLocks.Unlock(cacheKey) } - var receivedMessageMap = *receivedMessage + var jsonDiffPatch []byte - fileCacheDirPath, err := getSubscriptionCacheDirPath(bConn, queryId, true) - if err != nil { - log.Errorf("Error on get Client/Subscription cache path: %v", err) - return - } - filePath := fileCacheDirPath + dataKey + ".json" - - if !jsonDiffPatchExists { - if currDataChecksum == lastDataChecksum { - //Content didn't change, set message as null to avoid sending it to the browser - //This case is usual when the middleware reconnects with Hasura and receives the data again - *receivedMessage = nil - } else { - //Content was changed, creating json patch - //If data is small (< minLengthToPatch) it's not worth creating the patch - if len(string(dataAsJson)) > minLengthToPatch { - if lastContent, lastContentErr := ioutil.ReadFile(filePath); lastContentErr == nil && string(lastContent) != "" { - //Temporarily use CustomPatch only for UserList (testing feature) - if strings.HasPrefix(cacheKey, "subscription-Patched_UserListSubscription") && - common.ValidateIfShouldUseCustomJsonPatch(lastContent, dataAsJson, "userId") { - jsonDiffPatch = common.CreateJsonPatch(lastContent, dataAsJson, "userId") - common.StoreJsonPatchCache(cacheKey, jsonDiffPatch) - } else if diffPatch, diffPatchErr := jsonpatch.CreatePatch(lastContent, dataAsJson); diffPatchErr == nil { - if jsonDiffPatch, err = json.Marshal(diffPatch); err == nil { - common.StoreJsonPatchCache(cacheKey, jsonDiffPatch) - } else { - log.Errorf("Error marshaling patch array: %v", err) - } - } else { - log.Errorf("Error creating JSON patch: %v\n%v", diffPatchErr, string(dataAsJson)) + if currDataChecksum == lastDataChecksum { + //Content didn't change, set message as null to avoid sending it to the browser + //This case is usual when the middleware reconnects with Hasura and receives the data again + jsonData, _ := json.Marshal(nil) + common.StorePatchedMessageCache(cacheKey, jsonData) + return jsonData + } else { + //Content was changed, creating json patch + //If data is small (< minLengthToPatch) it's not worth creating the patch + if len(hasuraMessage.Payload.Data[dataKey]) > minLengthToPatch { + if string(lastHasuraMessage.Payload.Data[dataKey]) != "" { + var shouldUseCustomJsonPatch bool + if shouldUseCustomJsonPatch, jsonDiffPatch = common.ValidateIfShouldUseCustomJsonPatch( + lastHasuraMessage.Payload.Data[dataKey], + hasuraMessage.Payload.Data[dataKey], + "userId"); shouldUseCustomJsonPatch { + common.StorePatchedMessageCache(cacheKey, jsonDiffPatch) + } else if diffPatch, diffPatchErr := jsonpatch.CreatePatch(lastHasuraMessage.Payload.Data[dataKey], hasuraMessage.Payload.Data[dataKey]); diffPatchErr == nil { + var err error + if jsonDiffPatch, err = json.Marshal(diffPatch); err != nil { + log.Errorf("Error marshaling patch array: %v", err) } + } else { + log.Errorf("Error creating JSON patch: %v\n%v", diffPatchErr, string(hasuraMessage.Payload.Data[dataKey])) } } } } //Use patch if the length is {minShrinkToUsePatch}% smaller than the original msg - if jsonDiffPatch != nil && float64(len(string(jsonDiffPatch)))/float64(len(string(dataAsJson))) < minShrinkToUsePatch { + if jsonDiffPatch != nil && float64(len(string(jsonDiffPatch)))/float64(len(string(hasuraMessage.Payload.Data[dataKey]))) < minShrinkToUsePatch { //Modify receivedMessage to include the Patch and remove the previous data //The key of the original message is kept to avoid errors (Apollo-client expects to receive this prop) - receivedMessageMap["payload"] = map[string]interface{}{ - "data": map[string]interface{}{ - "patch": json.RawMessage(jsonDiffPatch), - dataKey: json.RawMessage("[]"), - }, + + hasuraMessage.Payload.Data = map[string]json.RawMessage{ + "patch": jsonDiffPatch, + dataKey: json.RawMessage("[]"), } - *receivedMessage = receivedMessageMap + hasuraMessageJson, _ := json.Marshal(hasuraMessage) + receivedMessage = hasuraMessageJson } - //Store current result to be used to create json patch in the future - if len(string(dataAsJson)) > minLengthToPatch || fileExists(filePath) { - errWritingOutput := ioutil.WriteFile(filePath, dataAsJson, 0644) - if errWritingOutput != nil { - log.Errorf("Error on trying to write cache of json diff: %v", errWritingOutput) - } - } + common.StorePatchedMessageCache(cacheKey, receivedMessage) + return receivedMessage } diff --git a/bbb-graphql-middleware/internal/websrv/connhandler.go b/bbb-graphql-middleware/internal/websrv/connhandler.go index defac4f3c6..7cb81fef1f 100644 --- a/bbb-graphql-middleware/internal/websrv/connhandler.go +++ b/bbb-graphql-middleware/internal/websrv/connhandler.go @@ -1,18 +1,23 @@ package websrv import ( + "bbb-graphql-middleware/config" + "bbb-graphql-middleware/internal/akka_apps" + "bbb-graphql-middleware/internal/bbb_web" + "bbb-graphql-middleware/internal/common" + "bbb-graphql-middleware/internal/gql_actions" + "bbb-graphql-middleware/internal/hasura" + "bbb-graphql-middleware/internal/websrv/reader" + "bbb-graphql-middleware/internal/websrv/writer" + "bytes" "context" + "encoding/json" "fmt" - "github.com/iMDT/bbb-graphql-middleware/internal/common" - "github.com/iMDT/bbb-graphql-middleware/internal/gql_actions" - "github.com/iMDT/bbb-graphql-middleware/internal/hasura" - "github.com/iMDT/bbb-graphql-middleware/internal/msgpatch" - "github.com/iMDT/bbb-graphql-middleware/internal/websrv/reader" - "github.com/iMDT/bbb-graphql-middleware/internal/websrv/writer" + "github.com/prometheus/client_golang/prometheus" log "github.com/sirupsen/logrus" "net/http" "nhooyr.io/websocket" - "os" + "strings" "sync" "time" ) @@ -30,8 +35,6 @@ var BrowserConnectionsMutex = &sync.RWMutex{} // This is the connection that comes from browser func ConnectionHandler(w http.ResponseWriter, r *http.Request) { log := log.WithField("_routine", "ConnectionHandler") - common.ActivitiesOverviewStarted("__BrowserConnection") - defer common.ActivitiesOverviewCompleted("__BrowserConnection") // Obtain id for this connection lastBrowserConnectionId++ @@ -44,10 +47,11 @@ func ConnectionHandler(w http.ResponseWriter, r *http.Request) { // Add sub-protocol var acceptOptions websocket.AcceptOptions - acceptOptions.Subprotocols = append(acceptOptions.Subprotocols, "graphql-ws") - bbbOrigin := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_ORIGIN") - if bbbOrigin != "" { - acceptOptions.OriginPatterns = append(acceptOptions.OriginPatterns, bbbOrigin) + acceptOptions.Subprotocols = append(acceptOptions.Subprotocols, "graphql-transport-ws") + + //Add Authorized Cross Origin Url + if config.GetConfig().Server.AuthorizedCrossOrigin != "" { + acceptOptions.OriginPatterns = append(acceptOptions.OriginPatterns, config.GetConfig().Server.AuthorizedCrossOrigin) } browserWsConn, err := websocket.Accept(w, r, &acceptOptions) @@ -55,13 +59,26 @@ func ConnectionHandler(w http.ResponseWriter, r *http.Request) { if err != nil { log.Errorf("error: %v", err) } + + if common.HasReachedMaxGlobalConnections() { + common.WsConnectionRejectedCounter.With(prometheus.Labels{"reason": "limit of server connections exceeded"}).Inc() + browserWsConn.Close(websocket.StatusInternalError, "limit of server connections exceeded") + return + } + defer browserWsConn.Close(websocket.StatusInternalError, "the sky is falling") var thisConnection = common.BrowserConnection{ - Id: browserConnectionId, - ActiveSubscriptions: make(map[string]common.GraphQlSubscription, 1), - Context: browserConnectionContext, - ConnAckSentToBrowser: false, + Id: browserConnectionId, + Websocket: browserWsConn, + BrowserRequestCookies: r.Cookies(), + ActiveSubscriptions: make(map[string]common.GraphQlSubscription, 1), + Context: browserConnectionContext, + ContextCancelFunc: browserConnectionContextCancel, + ConnAckSentToBrowser: false, + FromBrowserToHasuraChannel: common.NewSafeChannelByte(bufferSize), + FromBrowserToGqlActionsChannel: common.NewSafeChannelByte(bufferSize), + FromHasuraToBrowserChannel: common.NewSafeChannelByte(bufferSize), } BrowserConnectionsMutex.Lock() @@ -69,13 +86,15 @@ func ConnectionHandler(w http.ResponseWriter, r *http.Request) { BrowserConnectionsMutex.Unlock() defer func() { - msgpatch.RemoveConnCacheDir(browserConnectionId) BrowserConnectionsMutex.Lock() _, bcExists := BrowserConnections[browserConnectionId] if bcExists { sessionTokenRemoved := BrowserConnections[browserConnectionId].SessionToken delete(BrowserConnections, browserConnectionId) - go SendUserGraphqlConnectionClosedSysMsg(sessionTokenRemoved, browserConnectionId) + + if sessionTokenRemoved != "" { + go SendUserGraphqlConnectionClosedSysMsg(sessionTokenRemoved, browserConnectionId) + } } BrowserConnectionsMutex.Unlock() @@ -85,11 +104,42 @@ func ConnectionHandler(w http.ResponseWriter, r *http.Request) { // Log it log.Infof("connection accepted") - // Create channels - fromBrowserToHasuraConnectionEstablishingChannel := common.NewSafeChannel(bufferSize) - fromBrowserToHasuraChannel := common.NewSafeChannel(bufferSize) - fromBrowserToGqlActionsChannel := common.NewSafeChannel(bufferSize) - fromHasuraToBrowserChannel := common.NewSafeChannel(bufferSize) + // Configure the wait group (to hold this routine execution until both are completed) + var wgAll sync.WaitGroup + wgAll.Add(2) + + // Other wait group to close this connection once Browser Reader dies + var wgReader sync.WaitGroup + wgReader.Add(1) + + // Reads from browser connection, writes into fromBrowserToHasuraChannel + go reader.BrowserConnectionReader(&thisConnection, []*sync.WaitGroup{&wgAll, &wgReader}) + + go func() { + wgReader.Wait() + log.Debug("BrowserConnectionReader finished, closing Write Channel") + thisConnection.FromHasuraToBrowserChannel.Close() + thisConnection.Disconnected = true + }() + + //Check authorization and obtain user session variables from bbb-web + if errorOnInitConnection := connectionInitHandler(&thisConnection); errorOnInitConnection != nil { + common.WsConnectionRejectedCounter.With(prometheus.Labels{"reason": errorOnInitConnection.Error()}).Inc() + + //If the server wishes to reject the connection it is recommended to close the socket with `4403: Forbidden`. + //https://github.com/enisdenjo/graphql-ws/blob/63881c3372a3564bf42040e3f572dd74e41b2e49/PROTOCOL.md?plain=1#L36 + wsError := &websocket.CloseError{ + Code: websocket.StatusCode(4403), + Reason: errorOnInitConnection.Error(), + } + browserWsConn.Close(wsError.Code, wsError.Reason) + browserConnectionContextCancel() + } + + common.WsConnectionAcceptedCounter.Inc() + + common.AddUserConnection(thisConnection.SessionToken) + defer common.RemoveUserConnection(thisConnection.SessionToken) // Ensure a hasura client is running while the browser is connected go func() { @@ -108,7 +158,7 @@ func ConnectionHandler(w http.ResponseWriter, r *http.Request) { BrowserConnectionsMutex.RUnlock() if thisBrowserConnection != nil { log.Debugf("created hasura client") - hasura.HasuraClient(thisBrowserConnection, r.Cookies(), fromBrowserToHasuraChannel, fromHasuraToBrowserChannel) + hasura.HasuraClient(thisBrowserConnection) } time.Sleep(100 * time.Millisecond) } @@ -138,42 +188,16 @@ func ConnectionHandler(w http.ResponseWriter, r *http.Request) { thisBrowserConnection.GraphqlActionsContext, thisBrowserConnection.GraphqlActionsContextCancel = context.WithCancel(browserConnectionContext) BrowserConnectionsMutex.Unlock() - gql_actions.GraphqlActionsClient(thisBrowserConnection, r.Cookies(), fromBrowserToGqlActionsChannel, fromBrowserToHasuraChannel, fromHasuraToBrowserChannel) + gql_actions.GraphqlActionsClient(thisBrowserConnection) } - time.Sleep(100 * time.Millisecond) + time.Sleep(1000 * time.Millisecond) } } } }() - // Configure the wait group (to hold this routine execution until both are completed) - var wgAll sync.WaitGroup - wgAll.Add(3) - - var wgReader sync.WaitGroup - wgReader.Add(1) - - // Reads from browser connection, writes into fromBrowserToHasuraChannel and fromBrowserToHasuraConnectionEstablishingChannel - go reader.BrowserConnectionReader( - browserConnectionId, - browserConnectionContext, - browserConnectionContextCancel, - browserWsConn, - fromBrowserToGqlActionsChannel, - fromBrowserToHasuraChannel, - fromBrowserToHasuraConnectionEstablishingChannel, - []*sync.WaitGroup{&wgAll, &wgReader}) - go func() { - wgReader.Wait() - log.Debug("BrowserConnectionReader finished, closing Write Channel") - fromHasuraToBrowserChannel.Close() - thisConnection.Disconnected = true - }() - // Reads from fromHasuraToBrowserChannel, writes to browser connection - go writer.BrowserConnectionWriter(browserConnectionId, browserConnectionContext, browserWsConn, fromHasuraToBrowserChannel, &wgAll) - - go ConnectionInitHandler(browserConnectionId, browserConnectionContext, fromBrowserToHasuraConnectionEstablishingChannel, &wgAll) + go writer.BrowserConnectionWriter(&thisConnection, &wgAll) // Wait until all routines are finished wgAll.Wait() @@ -201,43 +225,167 @@ func InvalidateSessionTokenConnections(sessionTokenToInvalidate string) { } func invalidateHasuraConnectionForSessionToken(bc *common.BrowserConnection, sessionToken string) { + BrowserConnectionsMutex.RLock() + defer BrowserConnectionsMutex.RUnlock() + if bc.HasuraConnection == nil { return // If there's no Hasura connection, there's nothing to invalidate. } - hasuraConnectionId := bc.HasuraConnection.Id + log.Debugf("Processing invalidate request for sessionToken %v (hasura connection %v)", sessionToken, bc.HasuraConnection.Id) - // Send message to stop receiving new messages from the browser. - bc.HasuraConnection.FreezeMsgFromBrowserChan.Send(true) - bc.GraphqlActionsContextCancel() + // Stop receiving new messages from the browser. + log.Debug("freezing channel fromBrowserToHasuraChannel") + bc.FromBrowserToHasuraChannel.FreezeChannel() - // Wait until there are no active mutations. - for iterationCount := 0; iterationCount < 20; iterationCount++ { - activeMutationFound := false - bc.ActiveSubscriptionsMutex.RLock() - for _, subscription := range bc.ActiveSubscriptions { - if subscription.Type == common.Mutation { - activeMutationFound = true - break - } - } - bc.ActiveSubscriptionsMutex.RUnlock() - - if !activeMutationFound { - break // Exit the loop if no active mutations are found. - } - time.Sleep(100 * time.Millisecond) // Wait a bit before checking again. - } - - log.Debugf("Processing invalidate request for sessionToken %v (hasura connection %v)", sessionToken, hasuraConnectionId) + //Update variables for Mutations (gql-actions requests) + go refreshUserSessionVariables(bc) // Cancel the Hasura connection context to clean up resources. if bc.HasuraConnection != nil && bc.HasuraConnection.ContextCancelFunc != nil { bc.HasuraConnection.ContextCancelFunc() } - log.Debugf("Processed invalidate request for sessionToken %v (hasura connection %v)", sessionToken, hasuraConnectionId) - // Send a reconnection confirmation message go SendUserGraphqlReconnectionForcedEvtMsg(sessionToken) } + +func refreshUserSessionVariables(browserConnection *common.BrowserConnection) error { + BrowserConnectionsMutex.RLock() + sessionToken := browserConnection.SessionToken + browserConnectionId := browserConnection.Id + BrowserConnectionsMutex.RUnlock() + + // Check authorization + sessionVariables, err := akka_apps.AkkaAppsGetSessionVariablesFrom(browserConnectionId, sessionToken) + if err != nil { + log.Error(err) + return fmt.Errorf("error on checking sessionToken authorization") + } else { + log.Trace("Session variables obtained successfully") + } + + if _, exists := sessionVariables["x-hasura-role"]; !exists { + return fmt.Errorf("error on checking sessionToken authorization, X-Hasura-Role is missing") + } + + if _, exists := sessionVariables["x-hasura-userid"]; !exists { + return fmt.Errorf("error on checking sessionToken authorization, X-Hasura-UserId is missing") + } + + if _, exists := sessionVariables["x-hasura-meetingid"]; !exists { + return fmt.Errorf("error on checking sessionToken authorization, X-Hasura-MeetingId is missing") + } + + BrowserConnectionsMutex.Lock() + browserConnection.BBBWebSessionVariables = sessionVariables + BrowserConnectionsMutex.Unlock() + + return nil +} + +func connectionInitHandler(browserConnection *common.BrowserConnection) error { + BrowserConnectionsMutex.RLock() + browserConnectionId := browserConnection.Id + browserConnectionCookies := browserConnection.BrowserRequestCookies + BrowserConnectionsMutex.RUnlock() + + // Intercept the fromBrowserMessage channel to get the sessionToken + for { + fromBrowserMessage, ok := browserConnection.FromBrowserToHasuraChannel.Receive() + if !ok { + //Received all messages. Channel is closed + return fmt.Errorf("error on receiving init connection") + } + if bytes.Contains(fromBrowserMessage, []byte("\"connection_init\"")) { + var fromBrowserMessageAsMap map[string]interface{} + if err := json.Unmarshal(fromBrowserMessage, &fromBrowserMessageAsMap); err != nil { + log.Errorf("failed to unmarshal message: %v", err) + continue + } + + var payloadAsMap = fromBrowserMessageAsMap["payload"].(map[string]interface{}) + var headersAsMap = payloadAsMap["headers"].(map[string]interface{}) + var sessionToken, existsSessionToken = headersAsMap["X-Session-Token"].(string) + if !existsSessionToken { + return fmt.Errorf("X-Session-Token header missing on init connection") + } + + if common.HasReachedMaxUserConnections(sessionToken) { + return fmt.Errorf("too many connections") + } + + var clientSessionUUID, existsClientSessionUUID = headersAsMap["X-ClientSessionUUID"].(string) + if !existsClientSessionUUID { + return fmt.Errorf("X-ClientSessionUUID header missing on init connection") + } + + var clientType, existsClientType = headersAsMap["X-ClientType"].(string) + if !existsClientType { + return fmt.Errorf("X-ClientType header missing on init connection") + } + + var clientIsMobile, existsMobile = headersAsMap["X-ClientIsMobile"].(string) + if !existsMobile { + return fmt.Errorf("X-ClientIsMobile header missing on init connection") + } + + var meetingId, userId string + var errCheckAuthorization error + + // Check authorization + var numOfAttempts = 0 + for { + meetingId, userId, errCheckAuthorization = bbb_web.BBBWebCheckAuthorization(browserConnectionId, sessionToken, browserConnectionCookies) + if errCheckAuthorization != nil { + log.Error(errCheckAuthorization) + } + + if (errCheckAuthorization == nil && meetingId != "" && userId != "") || numOfAttempts > 5 { + break + } + numOfAttempts++ + time.Sleep(100 * time.Millisecond) + } + + if errCheckAuthorization != nil { + return fmt.Errorf("error on trying to check authorization") + } + + if meetingId == "" { + return fmt.Errorf("error to obtain user meetingId from BBBWebCheckAuthorization") + } + + if userId == "" { + return fmt.Errorf("error to obtain user userId from BBBWebCheckAuthorization") + } + + log.Trace("Success on check authorization") + + log.Debugf("[ConnectionInitHandler] intercepted Session Token %v and Client Session UUID %v", sessionToken, clientSessionUUID) + BrowserConnectionsMutex.Lock() + browserConnection.SessionToken = sessionToken + browserConnection.ClientSessionUUID = clientSessionUUID + browserConnection.MeetingId = meetingId + browserConnection.UserId = userId + browserConnection.ConnectionInitMessage = fromBrowserMessage + BrowserConnectionsMutex.Unlock() + + if err := refreshUserSessionVariables(browserConnection); err != nil { + return fmt.Errorf("error on getting session variables") + } + + go SendUserGraphqlConnectionEstablishedSysMsg( + sessionToken, + clientSessionUUID, + clientType, + strings.ToLower(clientIsMobile) == "true", + browserConnectionId, + ) + + break + } + } + + return nil +} diff --git a/bbb-graphql-middleware/internal/websrv/conninithandler.go b/bbb-graphql-middleware/internal/websrv/conninithandler.go deleted file mode 100644 index 67b0be3e42..0000000000 --- a/bbb-graphql-middleware/internal/websrv/conninithandler.go +++ /dev/null @@ -1,50 +0,0 @@ -package websrv - -import ( - "context" - "github.com/iMDT/bbb-graphql-middleware/internal/common" - log "github.com/sirupsen/logrus" - "sync" -) - -func ConnectionInitHandler(browserConnectionId string, browserConnectionContext context.Context, fromBrowserToHasuraConnectionEstablishingChannel *common.SafeChannel, wg *sync.WaitGroup) { - log := log.WithField("_routine", "ConnectionInitHandler").WithField("browserConnectionId", browserConnectionId) - - log.Debugf("starting") - - defer wg.Done() - defer log.Debugf("finished") - - BrowserConnectionsMutex.RLock() - browserConnection := BrowserConnections[browserConnectionId] - BrowserConnectionsMutex.RUnlock() - - // Intercept the fromBrowserMessage channel to get the sessionToken - for { - fromBrowserMessage, ok := fromBrowserToHasuraConnectionEstablishingChannel.Receive() - if !ok { - //Received all messages. Channel is closed - return - } - if browserConnection.SessionToken == "" { - var fromBrowserMessageAsMap = fromBrowserMessage.(map[string]interface{}) - - if fromBrowserMessageAsMap["type"] == "connection_init" { - var payloadAsMap = fromBrowserMessageAsMap["payload"].(map[string]interface{}) - var headersAsMap = payloadAsMap["headers"].(map[string]interface{}) - var sessionToken = headersAsMap["X-Session-Token"] - if sessionToken != nil { - sessionToken := headersAsMap["X-Session-Token"].(string) - log.Debugf("[SessionTokenReader] intercepted session token %v", sessionToken) - BrowserConnectionsMutex.Lock() - browserConnection.SessionToken = sessionToken - BrowserConnectionsMutex.Unlock() - - go SendUserGraphqlConnectionEstablishedSysMsg(sessionToken, browserConnectionId) - fromBrowserToHasuraConnectionEstablishingChannel.Close() - break - } - } - } - } -} diff --git a/bbb-graphql-middleware/internal/websrv/reader/reader.go b/bbb-graphql-middleware/internal/websrv/reader/reader.go index 85b4837279..004e1aacb0 100644 --- a/bbb-graphql-middleware/internal/websrv/reader/reader.go +++ b/bbb-graphql-middleware/internal/websrv/reader/reader.go @@ -1,34 +1,27 @@ package reader import ( + "bbb-graphql-middleware/internal/common" + "bytes" "context" + "encoding/json" "errors" - "github.com/iMDT/bbb-graphql-middleware/internal/common" log "github.com/sirupsen/logrus" "nhooyr.io/websocket" - "nhooyr.io/websocket/wsjson" - "strings" "sync" "time" ) func BrowserConnectionReader( - browserConnectionId string, - ctx context.Context, - ctxCancel context.CancelFunc, - browserWsConn *websocket.Conn, - fromBrowserToGqlActionsChannel *common.SafeChannel, - fromBrowserToHasuraChannel *common.SafeChannel, - fromBrowserToHasuraConnectionEstablishingChannel *common.SafeChannel, + browserConnection *common.BrowserConnection, waitGroups []*sync.WaitGroup) { - log := log.WithField("_routine", "BrowserConnectionReader").WithField("browserConnectionId", browserConnectionId) + log := log.WithField("_routine", "BrowserConnectionReader").WithField("browserConnectionId", browserConnection.Id) defer log.Debugf("finished") log.Debugf("starting") defer func() { - fromBrowserToHasuraChannel.Close() - fromBrowserToGqlActionsChannel.Close() - fromBrowserToHasuraConnectionEstablishingChannel.Close() + browserConnection.FromBrowserToHasuraChannel.Close() + browserConnection.FromBrowserToGqlActionsChannel.Close() }() defer func() { @@ -40,11 +33,10 @@ func BrowserConnectionReader( time.Sleep(100 * time.Millisecond) }() - defer ctxCancel() + defer browserConnection.ContextCancelFunc() for { - var v interface{} - err := wsjson.Read(ctx, browserWsConn, &v) + messageType, message, err := browserConnection.Websocket.Read(browserConnection.Context) if err != nil { if errors.Is(err, context.Canceled) { log.Debugf("Closing Browser ws connection as Context was cancelled!") @@ -54,26 +46,29 @@ func BrowserConnectionReader( return } - log.Tracef("received from browser: %v", v) + log.Tracef("received from browser: %s", string(message)) - if v == nil { + if messageType != websocket.MessageText { + log.Warnf("received non-text message: %v", messageType) continue } - var fromBrowserMessageAsMap = v.(map[string]interface{}) + var browserMessageType struct { + Type string `json:"type"` + } + err = json.Unmarshal(message, &browserMessageType) + if err != nil { + log.Errorf("failed to unmarshal message: %v", err) + continue + } - if payload, ok := fromBrowserMessageAsMap["payload"].(map[string]interface{}); ok { - if query, okQuery := payload["query"].(string); okQuery { - //Forward Mutations directly to GraphqlActions - //Update mutations must be handled by Hasura - if strings.HasPrefix(query, "mutation") && !strings.Contains(query, "update_") { - fromBrowserToGqlActionsChannel.Send(v) - continue - } + if browserMessageType.Type == "subscribe" { + if bytes.Contains(message, []byte("\"query\":\"mutation")) { + browserConnection.FromBrowserToGqlActionsChannel.Send(message) + continue } } - fromBrowserToHasuraChannel.Send(v) - fromBrowserToHasuraConnectionEstablishingChannel.Send(v) + browserConnection.FromBrowserToHasuraChannel.Send(message) } } diff --git a/bbb-graphql-middleware/internal/websrv/rediscli.go b/bbb-graphql-middleware/internal/websrv/rediscli.go index 9433bfafe0..6441f7d4df 100644 --- a/bbb-graphql-middleware/internal/websrv/rediscli.go +++ b/bbb-graphql-middleware/internal/websrv/rediscli.go @@ -1,19 +1,20 @@ package websrv import ( + "bbb-graphql-middleware/config" + "bbb-graphql-middleware/internal/common" "context" "encoding/json" - "github.com/iMDT/bbb-graphql-middleware/internal/common" + "fmt" "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" - "os" "strings" "time" ) var redisClient = redis.NewClient(&redis.Options{ - Addr: os.Getenv("BBB_GRAPHQL_MIDDLEWARE_REDIS_ADDRESS"), - Password: os.Getenv("BBB_GRAPHQL_MIDDLEWARE_REDIS_PASSWORD"), + Addr: fmt.Sprintf("%s:%d", config.GetConfig().Redis.Host, config.GetConfig().Redis.Port), + Password: config.GetConfig().Redis.Password, DB: 0, }) @@ -113,7 +114,7 @@ func sendBbbCoreMsgToRedis(name string, body map[string]interface{}) { return } - log.Tracef("JSON message sent to channel %s:\n%s\n", channelName, messageJSON) + log.Tracef("JSON message sent to channel %s:\n%s\n", channelName, string(messageJSON)) } func SendUserGraphqlReconnectionForcedEvtMsg(sessionToken string) { @@ -125,10 +126,18 @@ func SendUserGraphqlReconnectionForcedEvtMsg(sessionToken string) { sendBbbCoreMsgToRedis("UserGraphqlReconnectionForcedEvtMsg", body) } -func SendUserGraphqlConnectionEstablishedSysMsg(sessionToken string, browserConnectionId string) { +func SendUserGraphqlConnectionEstablishedSysMsg( + sessionToken string, + clientSessionUUID string, + clientType string, + clientIsMobile bool, + browserConnectionId string) { var body = map[string]interface{}{ "middlewareUID": common.GetUniqueID(), "sessionToken": sessionToken, + "clientSessionUUID": clientSessionUUID, + "clientType": clientType, + "clientIsMobile": clientIsMobile, "browserConnectionId": browserConnectionId, } diff --git a/bbb-graphql-middleware/internal/websrv/writer/writer.go b/bbb-graphql-middleware/internal/websrv/writer/writer.go index b478ba61fa..9a4aca5ef8 100644 --- a/bbb-graphql-middleware/internal/websrv/writer/writer.go +++ b/bbb-graphql-middleware/internal/websrv/writer/writer.go @@ -1,16 +1,18 @@ package writer import ( - "context" - "github.com/iMDT/bbb-graphql-middleware/internal/common" + "bbb-graphql-middleware/internal/common" + "bytes" + "encoding/json" log "github.com/sirupsen/logrus" "nhooyr.io/websocket" - "nhooyr.io/websocket/wsjson" "sync" ) -func BrowserConnectionWriter(browserConnectionId string, ctx context.Context, browserWsConn *websocket.Conn, fromHasuraToBrowserChannel *common.SafeChannel, wg *sync.WaitGroup) { - log := log.WithField("_routine", "BrowserConnectionWriter").WithField("browserConnectionId", browserConnectionId) +func BrowserConnectionWriter( + browserConnection *common.BrowserConnection, + wg *sync.WaitGroup) { + log := log.WithField("_routine", "BrowserConnectionWriter").WithField("browserConnectionId", browserConnection.Id) defer log.Debugf("finished") log.Debugf("starting") defer wg.Done() @@ -18,22 +20,20 @@ func BrowserConnectionWriter(browserConnectionId string, ctx context.Context, br RangeLoop: for { select { - case <-ctx.Done(): + case <-browserConnection.Context.Done(): log.Debug("Browser context cancelled.") break RangeLoop - case toBrowserMessage := <-fromHasuraToBrowserChannel.ReceiveChannel(): + case toBrowserMessage := <-browserConnection.FromHasuraToBrowserChannel.ReceiveChannel(): { if toBrowserMessage == nil { - if fromHasuraToBrowserChannel.Closed() { + if browserConnection.FromHasuraToBrowserChannel.Closed() { break RangeLoop } continue } - var toBrowserMessageAsMap = toBrowserMessage.(map[string]interface{}) - - log.Tracef("sending to browser: %v", toBrowserMessage) - err := wsjson.Write(ctx, browserWsConn, toBrowserMessage) + log.Tracef("sending to browser: %s", string(toBrowserMessage)) + err := browserConnection.Websocket.Write(browserConnection.Context, websocket.MessageText, toBrowserMessage) if err != nil { log.Debugf("Browser is disconnected, skipping writing of ws message: %v", err) return @@ -41,9 +41,15 @@ RangeLoop: // After the error is sent to client, close its connection // Authentication hook unauthorized this request - if toBrowserMessageAsMap["type"] == "connection_error" { - var payloadAsString = toBrowserMessageAsMap["payload"].(string) - browserWsConn.Close(websocket.StatusInternalError, payloadAsString) + if bytes.Contains(toBrowserMessage, []byte("connection_error")) { + type HasuraMessage struct { + Type string `json:"type"` + } + var hasuraMessage HasuraMessage + _ = json.Unmarshal(toBrowserMessage, &hasuraMessage) + if hasuraMessage.Type == "connection_error" { + _ = browserConnection.Websocket.Close(websocket.StatusInternalError, string(toBrowserMessage)) + } } } } diff --git a/bbb-graphql-middleware/run-dev.sh b/bbb-graphql-middleware/run-dev.sh index d419a64f96..3b97b6892c 100755 --- a/bbb-graphql-middleware/run-dev.sh +++ b/bbb-graphql-middleware/run-dev.sh @@ -2,6 +2,6 @@ sudo systemctl stop bbb-graphql-middleware set -a # Automatically export all variables -source ./bbb-graphql-middleware-config.env +source /etc/default/bbb-graphql-middleware set +a # Stop automatically exporting go run cmd/bbb-graphql-middleware/main.go --signal SIGTERM diff --git a/bbb-graphql-server/bbb_schema.sql b/bbb-graphql-server/bbb_schema.sql index a5588cf90e..038c6c2c6c 100644 --- a/bbb-graphql-server/bbb_schema.sql +++ b/bbb-graphql-server/bbb_schema.sql @@ -5,6 +5,17 @@ CREATE OR REPLACE FUNCTION immutable_lower_unaccent(text) SELECT lower(unaccent('unaccent', $1)) $$ LANGUAGE SQL IMMUTABLE; +--remove_emojis will be used to create nameSortable +CREATE OR REPLACE FUNCTION remove_emojis(text) RETURNS text AS $$ +DECLARE + input_string ALIAS FOR $1; + output_string text; +BEGIN + output_string := regexp_replace(input_string, '[^\u0000-\uFFFF]', '', 'g'); + RETURN output_string; +END; +$$ LANGUAGE plpgsql IMMUTABLE; + -- ========== Meeting tables create table "meeting" ( @@ -22,6 +33,7 @@ create table "meeting" ( "loginUrl" varchar(500), "logoutUrl" varchar(500), "customLogoUrl" varchar(500), + "customDarkLogoUrl" varchar(500), "bannerText" text, "bannerColor" varchar(50), "createdTime" bigint, @@ -110,7 +122,6 @@ FROM ( create table "meeting_welcome" ( "meetingId" varchar(100) primary key references "meeting"("meetingId") ON DELETE CASCADE, - "welcomeMsgTemplate" text, "welcomeMsg" text, "welcomeMsgForModerators" text ); @@ -256,6 +267,7 @@ CREATE TABLE "user" ( "name" varchar(255), "role" varchar(20), "avatar" varchar(500), + "webcamBackground" varchar(500), "color" varchar(7), "sessionToken" varchar(16), "authToken" varchar(16), @@ -275,8 +287,8 @@ CREATE TABLE "user" ( "raiseHandTime" timestamp with time zone, "away" bool default false, "awayTime" timestamp with time zone, - "emoji" varchar, - "emojiTime" timestamp with time zone, + "reactionEmoji" varchar(25), + "reactionEmojiTime" timestamp with time zone, "guestStatusSetByModerator" varchar(50), "guestLobbyMessage" text, "mobile" bool, @@ -292,6 +304,7 @@ CREATE TABLE "user" ( "pinned" bool, "locked" bool, "speechLocale" varchar(255), + "captionLocale" varchar(255), "inactivityWarningDisplay" bool default FALSE, "inactivityWarningTimeoutSecs" numeric, "hasDrawPermissionOnCurrentPage" bool default FALSE, @@ -309,8 +322,7 @@ COMMENT ON COLUMN "user"."disconnected" IS 'This column is set true when the use COMMENT ON COLUMN "user"."expired" IS 'This column is set true after 10 seconds with disconnected=true'; COMMENT ON COLUMN "user"."loggedOut" IS 'This column is set to true when the user click the button to Leave meeting'; - ---Virtual columns isDialIn, isModerator, isOnline, isWaiting, isAllowed, isDenied +--Virtual columns isDialIn, isModerator, currentlyInMeeting, isWaiting, isAllowed, isDenied ALTER TABLE "user" ADD COLUMN "isDialIn" boolean GENERATED ALWAYS AS ("clientType" = 'dial-in-user') STORED; ALTER TABLE "user" ADD COLUMN "isWaiting" boolean GENERATED ALWAYS AS ("guestStatus" = 'WAIT') STORED; ALTER TABLE "user" ADD COLUMN "isAllowed" boolean GENERATED ALWAYS AS ("guestStatus" = 'ALLOW') STORED; @@ -319,45 +331,20 @@ ALTER TABLE "user" ADD COLUMN "isDenied" boolean GENERATED ALWAYS AS ("guestStat ALTER TABLE "user" ADD COLUMN "registeredAt" timestamp with time zone GENERATED ALWAYS AS (to_timestamp("registeredOn"::double precision / 1000)) STORED; --Used to sort the Userlist -ALTER TABLE "user" ADD COLUMN "nameSortable" varchar(255) GENERATED ALWAYS AS (immutable_lower_unaccent("name")) STORED; +ALTER TABLE "user" ADD COLUMN "nameSortable" varchar(255) GENERATED ALWAYS AS (trim(remove_emojis(immutable_lower_unaccent("name")))) STORED; CREATE INDEX "idx_user_waiting" ON "user"("meetingId") where "isWaiting" is true; ---ALTER TABLE "user" ADD COLUMN "isModerator" boolean GENERATED ALWAYS AS (CASE WHEN "role" = 'MODERATOR' THEN true ELSE false END) STORED; ---ALTER TABLE "user" ADD COLUMN "isOnline" boolean GENERATED ALWAYS AS (CASE WHEN "joined" IS true AND "loggedOut" IS false THEN true ELSE false END) STORED; - --- user (on update emoji, raiseHand or away: set new time) -CREATE OR REPLACE FUNCTION update_user_emoji_time_trigger_func() -RETURNS TRIGGER AS $$ -BEGIN - IF NEW."emoji" <> OLD."emoji" THEN - IF NEW."emoji" = 'none' or NEW."emoji" = '' THEN - NEW."emojiTime" := NULL; - ELSE - NEW."emojiTime" := NOW(); - END IF; - END IF; - IF NEW."raiseHand" IS DISTINCT FROM OLD."raiseHand" THEN - IF NEW."raiseHand" is false THEN - NEW."raiseHandTime" := NULL; - ELSE - NEW."raiseHandTime" := NOW(); - END IF; - END IF; - IF NEW."away" IS DISTINCT FROM OLD."away" THEN - IF NEW."away" is false THEN - NEW."awayTime" := NULL; - ELSE - NEW."awayTime" := NOW(); - END IF; - END IF; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; - -CREATE TRIGGER update_user_emoji_time_trigger BEFORE UPDATE OF "emoji" ON "user" - FOR EACH ROW EXECUTE FUNCTION update_user_emoji_time_trigger_func(); - +ALTER TABLE "user" ADD COLUMN "isModerator" boolean GENERATED ALWAYS AS (CASE WHEN "role" = 'MODERATOR' THEN true ELSE false END) STORED; +ALTER TABLE "user" ADD COLUMN "currentlyInMeeting" boolean GENERATED ALWAYS AS ( + CASE WHEN + "user"."joined" IS true + AND "user"."expired" IS false + AND "user"."loggedOut" IS false + AND "user"."ejected" IS NOT true + THEN true + ELSE false + END) STORED; CREATE OR REPLACE VIEW "v_user" AS SELECT "user"."userId", @@ -371,8 +358,8 @@ AS SELECT "user"."userId", "user"."awayTime", "user"."raiseHand", "user"."raiseHandTime", - "user"."emoji", - "user"."emojiTime", + "user"."reactionEmoji", + "user"."reactionEmojiTime", "user"."guest", "user"."guestStatus", "user"."mobile", @@ -391,15 +378,13 @@ AS SELECT "user"."userId", "user"."pinned", CASE WHEN "user"."role" = 'MODERATOR' THEN false ELSE "user"."locked" END "locked", "user"."speechLocale", + "user"."captionLocale", CASE WHEN "user"."echoTestRunningAt" > current_timestamp - INTERVAL '3 seconds' THEN TRUE ELSE FALSE END "isRunningEchoTest", "user"."hasDrawPermissionOnCurrentPage", CASE WHEN "user"."role" = 'MODERATOR' THEN true ELSE false END "isModerator", - CASE WHEN "user"."joined" IS true AND "user"."expired" IS false AND "user"."loggedOut" IS false AND "user"."ejected" IS NOT TRUE THEN true ELSE false END "isOnline" - FROM "user" - WHERE "user"."loggedOut" IS FALSE - AND "user"."expired" IS FALSE - AND "user"."ejected" IS NOT TRUE - AND "user"."joined" IS TRUE; + "user"."currentlyInMeeting" + FROM "user" + WHERE "user"."currentlyInMeeting" is true; CREATE INDEX "idx_v_user_meetingId" ON "user"("meetingId") where "user"."loggedOut" IS FALSE @@ -407,11 +392,18 @@ CREATE INDEX "idx_v_user_meetingId" ON "user"("meetingId") AND "user"."ejected" IS NOT TRUE and "user"."joined" IS TRUE; -CREATE INDEX "idx_v_user_meetingId_orderByColumns" ON "user"("meetingId","role","raiseHandTime","awayTime","emojiTime","isDialIn","hasDrawPermissionOnCurrentPage","nameSortable","userId") - where "user"."loggedOut" IS FALSE - AND "user"."expired" IS FALSE - AND "user"."ejected" IS NOT TRUE - and "user"."joined" IS TRUE; +CREATE INDEX "idx_v_user_meetingId_orderByColumns" ON "user"( + "meetingId", + "presenter", + "role", + "raiseHandTime", + "isDialIn", + "hasDrawPermissionOnCurrentPage", + "nameSortable", + "registeredAt", + "userId" + ) + where "user"."currentlyInMeeting" is true; CREATE OR REPLACE VIEW "v_user_current" AS SELECT "user"."userId", @@ -421,10 +413,11 @@ AS SELECT "user"."userId", "user"."name", "user"."nameSortable", "user"."avatar", + "user"."webcamBackground", "user"."color", "user"."away", "user"."raiseHand", - "user"."emoji", + "user"."reactionEmoji", "user"."guest", "user"."guestStatus", "user"."mobile", @@ -449,22 +442,16 @@ AS SELECT "user"."userId", "user"."pinned", CASE WHEN "user"."role" = 'MODERATOR' THEN false ELSE "user"."locked" END "locked", "user"."speechLocale", + "user"."captionLocale", "user"."hasDrawPermissionOnCurrentPage", "user"."echoTestRunningAt", CASE WHEN "user"."echoTestRunningAt" > current_timestamp - INTERVAL '3 seconds' THEN TRUE ELSE FALSE END "isRunningEchoTest", CASE WHEN "user"."role" = 'MODERATOR' THEN true ELSE false END "isModerator", - CASE WHEN "user"."joined" IS true AND "user"."expired" IS false AND "user"."loggedOut" IS false AND "user"."ejected" IS NOT TRUE THEN true ELSE false END "isOnline", + "user"."currentlyInMeeting", "user"."inactivityWarningDisplay", "user"."inactivityWarningTimeoutSecs" FROM "user"; ---This view will be used by Meteor to validate if the provided authToken is valid ---It is temporary while Meteor is not removed -create view "v_user_connection_auth" as -select "meetingId", "userId", "authToken" -from "v_user_current" -where "isOnline" is true; - CREATE OR REPLACE VIEW "v_user_guest" AS SELECT u."meetingId", u."userId", u."guestStatus", @@ -478,7 +465,8 @@ u."isDenied", COALESCE(NULLIF(u."guestLobbyMessage",''),NULLIF(mup."guestLobbyMessage",'')) AS "guestLobbyMessage" FROM "user" u JOIN "meeting_usersPolicies" mup using("meetingId") -where u."guestStatus" = 'WAIT'; +where u."guestStatus" = 'WAIT' +and u."loggedOut" is false; --v_user_ref will be used only as foreign key (not possible to fetch this table directly through graphql) --it is necessary because v_user has some conditions like "lockSettings-hideUserList" @@ -494,7 +482,7 @@ AS SELECT "user"."color", "user"."away", "user"."raiseHand", - "user"."emoji", + "user"."reactionEmoji", "user"."guest", "user"."guestStatus", "user"."mobile", @@ -513,24 +501,25 @@ AS SELECT "user"."pinned", CASE WHEN "user"."role" = 'MODERATOR' THEN false ELSE "user"."locked" END "locked", "user"."speechLocale", + "user"."captionLocale", "user"."hasDrawPermissionOnCurrentPage", CASE WHEN "user"."role" = 'MODERATOR' THEN true ELSE false END "isModerator", - CASE WHEN "user"."joined" IS true AND "user"."expired" IS false AND "user"."loggedOut" IS false AND "user"."ejected" IS NOT TRUE THEN true ELSE false END "isOnline" + "user"."currentlyInMeeting" FROM "user"; -create table "user_customParameter"( +create table "user_metadata"( "meetingId" varchar(100), "userId" varchar(50), "parameter" varchar(255), "value" varchar(255), - CONSTRAINT "user_customParameter_pkey" PRIMARY KEY ("meetingId", "userId","parameter"), + CONSTRAINT "user_metadata_pkey" PRIMARY KEY ("meetingId", "userId","parameter"), FOREIGN KEY ("meetingId", "userId") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE ); -create index "idx_user_customParameter_pk_reverse" on "user_customParameter" ("userId", "meetingId"); +create index "idx_user_metadata_pk_reverse" on "user_metadata" ("userId", "meetingId"); -CREATE VIEW "v_user_customParameter" AS +CREATE VIEW "v_user_metadata" AS SELECT * -FROM "user_customParameter"; +FROM "user_metadata"; CREATE VIEW "v_user_welcomeMsgs" AS SELECT @@ -562,6 +551,7 @@ CREATE TABLE "user_voice" ( "voiceConfCallState" varchar(30), "endTime" bigint, "startTime" bigint, + "voiceActivityAt" timestamp with time zone, CONSTRAINT "user_voice_pkey" PRIMARY KEY ("meetingId","userId"), FOREIGN KEY ("meetingId", "userId") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE ); @@ -570,8 +560,8 @@ create index "idx_user_voice_pk_reverse" on "user_voice" ("userId", "meetingId") --CREATE INDEX "idx_user_voice_userId" ON "user_voice"("userId"); -- + 6000 means it will hide after 6 seconds -ALTER TABLE "user_voice" ADD COLUMN "hideTalkingIndicatorAt" timestamp with time zone -GENERATED ALWAYS AS (to_timestamp((COALESCE("endTime","startTime") + 6000) / 1000)) STORED; +--ALTER TABLE "user_voice" ADD COLUMN "hideTalkingIndicatorAt" timestamp with time zone +--GENERATED ALWAYS AS (to_timestamp((COALESCE("endTime","startTime") + 6000) / 1000)) STORED; ALTER TABLE "user_voice" ADD COLUMN "startedAt" timestamp with time zone GENERATED ALWAYS AS (to_timestamp("startTime"::double precision / 1000)) STORED; @@ -580,95 +570,56 @@ ALTER TABLE "user_voice" ADD COLUMN "endedAt" timestamp with time zone GENERATED ALWAYS AS (to_timestamp("endTime"::double precision / 1000)) STORED; CREATE INDEX "idx_user_voice_userId_talking" ON "user_voice"("meetingId", "userId","talking"); -CREATE INDEX "idx_user_voice_userId_hideTalkingIndicatorAt" ON "user_voice"("meetingId", "userId","hideTalkingIndicatorAt"); +--CREATE INDEX "idx_user_voice_userId_hideTalkingIndicatorAt" ON "user_voice"("meetingId", "userId","hideTalkingIndicatorAt"); +CREATE INDEX "idx_user_voice_userId_voiceActivityAt" ON "user_voice"("meetingId", "voiceActivityAt") WHERE "voiceActivityAt" is not null; CREATE OR REPLACE VIEW "v_user_voice" AS -SELECT - "user_voice" .*, - greatest(coalesce(user_voice."startTime", 0), coalesce(user_voice."endTime", 0)) AS "lastSpeakChangedAt", - user_talking."userId" IS NOT NULL "showTalkingIndicator" +SELECT "user_voice".* FROM "user_voice" -LEFT JOIN "user_voice" user_talking ON ( - user_talking."meetingId" = user_voice."meetingId" and - user_talking."userId" = user_voice."userId" and - user_talking."talking" IS TRUE - ) - OR - ( - user_talking."meetingId" = user_voice."meetingId" and - user_talking."userId" = user_voice."userId" and - user_talking."hideTalkingIndicatorAt" > now() - ) WHERE "user_voice"."joined" is true; - - ----TEMPORARY MINIMONGO ADAPTER START -alter table "user" add "voiceUpdatedAt" timestamp with time zone; - -CREATE OR REPLACE FUNCTION "update_user_voiceUpdatedAt_func"() RETURNS TRIGGER AS $$ +--Populate voiceActivityAt to provide users that are active in audio via stream subscription using the view v_user_voice_activity +CREATE OR REPLACE FUNCTION "update_user_voice_voiceActivityAt_trigger_func"() RETURNS TRIGGER AS $$ BEGIN - UPDATE "user" - SET "voiceUpdatedAt" = current_timestamp - WHERE "meetingId" = NEW."meetingId" AND "userId" = NEW."userId"; - RETURN NEW; + NEW."voiceActivityAt" := CASE WHEN + NEW."muted" IS false + or (OLD."muted" IS false and NEW."muted" is true) + or NEW."talking" is true + or (OLD."talking" IS true and NEW."talking" is false) + or (NEW."startTime" != OLD."startTime") + or (NEW."endTime" != OLD."endTime") + THEN current_timestamp + ELSE OLD."voiceActivityAt" + END; + RETURN NEW; END; $$ LANGUAGE plpgsql; -CREATE TRIGGER "update_user_voice_trigger" BEFORE UPDATE ON "user_voice" FOR EACH ROW -EXECUTE FUNCTION "update_user_voiceUpdatedAt_func"(); +CREATE TRIGGER "update_user_voice_voiceActivityAt_trigger" BEFORE INSERT OR UPDATE ON "user_voice" FOR EACH ROW +EXECUTE FUNCTION "update_user_voice_voiceActivityAt_trigger_func"(); -CREATE TRIGGER "insert_user_voice_trigger" BEFORE INSERT ON "user_voice" FOR EACH ROW -EXECUTE FUNCTION "update_user_voiceUpdatedAt_func"(); - -CREATE TRIGGER "delete_user_voice_trigger" AFTER DELETE ON "user_voice" FOR EACH ROW -EXECUTE FUNCTION "update_user_voiceUpdatedAt_func"(); - -CREATE OR REPLACE VIEW "v_user_voice_mongodb_adapter" AS -SELECT - u."meetingId", - u."userId", - u."voiceUpdatedAt", - "user_voice"."voiceUserId", - "user_voice"."callerName", - "user_voice"."callerNum", - "user_voice"."callingWith", - "user_voice"."joined", - "user_voice"."listenOnly", +CREATE OR REPLACE VIEW "v_user_voice_activity" AS +select + "user_voice"."meetingId", + "user_voice"."userId", "user_voice"."muted", - "user_voice"."spoke", "user_voice"."talking", - "user_voice"."floor", - "user_voice"."lastFloorTime", - "user_voice"."voiceConf", - "user_voice"."voiceConfCallSession", - "user_voice"."voiceConfClientSession", - "user_voice"."voiceConfCallState", - "user_voice"."endTime", - "user_voice"."startTime", - "user_voice"."hideTalkingIndicatorAt", - "user_voice"."startedAt", - "user_voice"."endedAt", - greatest(coalesce(user_voice."startTime", 0), coalesce(user_voice."endTime", 0)) AS "lastSpeakChangedAt", - user_talking."userId" IS NOT NULL "showTalkingIndicator" -FROM "user" u -LEFT JOIN "user_voice" ON "user_voice"."meetingId" = u."meetingId" AND "user_voice"."userId" = u."userId" -LEFT JOIN "user_voice" user_talking ON ( - user_talking."meetingId" = u."meetingId" and - user_talking."userId" = u."userId" and - user_talking."talking" IS TRUE - ) - OR ( - user_talking."meetingId" = u."meetingId" and - user_talking."userId" = u."userId" and - user_talking."hideTalkingIndicatorAt" > now() - ); ----TEMPORARY MINIMONGO ADAPTER END - + "user_voice"."startTime", + "user_voice"."endTime", + "user_voice"."voiceActivityAt" +FROM "user_voice" +WHERE "voiceActivityAt" is not null +AND --filter recent activities to avoid receiving all history every time it starts the streming + ("voiceActivityAt" > current_timestamp - '10 seconds'::interval + OR "user_voice"."muted" is false + OR "user_voice"."talking" is true + ) +; +---- CREATE TABLE "user_camera" ( - "streamId" varchar(100) PRIMARY KEY, + "streamId" varchar(150) PRIMARY KEY, "meetingId" varchar(100), "userId" varchar(50), FOREIGN KEY ("meetingId", "userId") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE @@ -713,11 +664,11 @@ create view "v_user_connectionStatus" as select * from "user_connectionStatus"; --Populate connectionAliveAtMaxIntervalMs to calc clientNotResponding ---It will sum settings public.stats.interval + public.stats.rtt (critical) +--It will sum settings public.stats.interval + public.stats.rtt.critical CREATE OR REPLACE FUNCTION "update_connectionAliveAtMaxIntervalMs"() RETURNS TRIGGER AS $$ BEGIN - SELECT ("clientSettingsJson"->'public'->'stats'->'rtt'->>(jsonb_array_length("clientSettingsJson"->'public'->'stats'->'rtt') - 1))::int + SELECT ("clientSettingsJson"->'public'->'stats'->'rtt'->'critical')::int + ("clientSettingsJson"->'public'->'stats'->'interval')::int INTO NEW."connectionAliveAtMaxIntervalMs" @@ -795,8 +746,12 @@ CREATE OR REPLACE VIEW "v_user_connectionStatusReport" AS SELECT u."meetingId", u."userId", max(cs."connectionAliveAt") AS "connectionAliveAt", max(cs."status") AS "currentStatus", ---COALESCE(max(cs."applicationRttInMs"),(EXTRACT(EPOCH FROM (current_timestamp - max(cs."connectionAliveAt"))) * 1000)) AS "applicationRttInMs", -CASE WHEN max(cs."connectionAliveAt") < current_timestamp - INTERVAL '1 millisecond' * max(cs."connectionAliveAtMaxIntervalMs") THEN TRUE ELSE FALSE END AS "clientNotResponding", +CASE WHEN + u."currentlyInMeeting" + AND max(cs."connectionAliveAt") < current_timestamp - INTERVAL '1 millisecond' * max(cs."connectionAliveAtMaxIntervalMs") + THEN TRUE + ELSE FALSE +END AS "clientNotResponding", (array_agg(csm."status" ORDER BY csm."lastOccurrenceAt" DESC))[1] as "lastUnstableStatus", max(csm."lastOccurrenceAt") AS "lastUnstableStatusAt" FROM "user" u @@ -810,6 +765,9 @@ CREATE INDEX "idx_user_connectionStatusMetrics_UnstableReport" ON "user_connecti CREATE TABLE "user_graphqlConnection" ( "graphqlConnectionId" serial PRIMARY KEY, "sessionToken" varchar(16), + "clientSessionUUID" varchar(36), + "clientType" varchar(50), + "clientIsMobile" bool, "middlewareUID" varchar(36), "middlewareConnectionId" varchar(12), "establishedAt" timestamp with time zone, @@ -861,9 +819,15 @@ CREATE TABLE "user_reaction" ( ); create index "idx_user_reaction_user_meeting" on "user_reaction" ("userId", "meetingId"); ---Set expiresAt on isert or update user_reaction +--Set expiresAt on insert or update user_reaction +--Set user.reactionEmoji with the latest emoji inserted CREATE OR REPLACE FUNCTION "update_user_reaction_trigger_func"() RETURNS TRIGGER AS $$ BEGIN + UPDATE "user" + SET "reactionEmoji" = nullif(lower(NEW."reactionEmoji"),'none'), + "reactionEmojiTime" = case when NULLIF(LOWER(NEW."reactionEmoji"),'none') is null then null else current_timestamp end + WHERE "userId" = NEW."userId" AND "meetingId" = NEW."meetingId"; + NEW."expiresAt" := NEW."createdAt" + '1 seconds'::INTERVAL * NEW."durationInSeconds"; RETURN NEW; END; @@ -881,12 +845,8 @@ CREATE INDEX "idx_user_reaction_userId_createdAt" ON "user_reaction"("meetingId" CREATE VIEW v_user_reaction AS SELECT ur."meetingId", ur."userId", ur."reactionEmoji", ur."createdAt", ur."expiresAt" -FROM "user_reaction" ur; - -CREATE VIEW v_user_reaction_current AS -SELECT ur."meetingId", ur."userId", (array_agg(ur."reactionEmoji" ORDER BY ur."expiresAt" DESC))[1] as "reactionEmoji" FROM "user_reaction" ur -GROUP BY ur."meetingId", ur."userId"; +WHERE "expiresAt" >= current_timestamp; CREATE TABLE "user_transcriptionError"( "meetingId" varchar(100), @@ -1070,9 +1030,13 @@ SELECT cu."meetingId", cm."senderId", cm."senderName", cm."senderRole", - cm."createdAt" + cm."createdAt", + CASE WHEN chat_with."lastSeenAt" >= cm."createdAt" THEN true ELSE false end "recipientHasSeen" FROM chat_message cm JOIN chat_user cu ON cu."meetingId" = cm."meetingId" AND cu."chatId" = cm."chatId" +LEFT JOIN "chat_user" chat_with ON chat_with."meetingId" = cm."meetingId" + AND chat_with."chatId" = cm."chatId" + AND chat_with."userId" != cu."userId" WHERE cm."chatId" != 'MAIN-PUBLIC-GROUP-CHAT'; --============ Presentation / Annotation @@ -1124,7 +1088,8 @@ CREATE TABLE "pres_page" ( "viewBoxHeight" NUMERIC, "maxImageWidth" integer, "maxImageHeight" integer, - "uploadCompleted" boolean + "uploadCompleted" boolean, + "infiniteWhiteboard" boolean ); CREATE INDEX "idx_pres_page_presentationId" ON "pres_page"("presentationId"); CREATE INDEX "idx_pres_page_presentationId_curr" ON "pres_page"("presentationId") where "current" is true; @@ -1182,7 +1147,8 @@ SELECT pres_presentation."meetingId", (pres_page."height" * LEAST(pres_page."maxImageWidth" / pres_page."width", pres_page."maxImageHeight" / pres_page."height")) AS "scaledHeight", (pres_page."width" * pres_page."widthRatio" / 100 * LEAST(pres_page."maxImageWidth" / pres_page."width", pres_page."maxImageHeight" / pres_page."height")) AS "scaledViewBoxWidth", (pres_page."height" * pres_page."heightRatio" / 100 * LEAST(pres_page."maxImageWidth" / pres_page."width", pres_page."maxImageHeight" / pres_page."height")) AS "scaledViewBoxHeight", - pres_page."uploadCompleted" + pres_page."uploadCompleted", + pres_page."infiniteWhiteboard" FROM pres_page JOIN pres_presentation ON pres_presentation."presentationId" = pres_page."presentationId"; @@ -1214,7 +1180,8 @@ SELECT pres_presentation."meetingId", (pres_page."width" * LEAST(pres_page."maxImageWidth" / pres_page."width", pres_page."maxImageHeight" / pres_page."height")) AS "scaledWidth", (pres_page."height" * LEAST(pres_page."maxImageWidth" / pres_page."width", pres_page."maxImageHeight" / pres_page."height")) AS "scaledHeight", (pres_page."width" * pres_page."widthRatio" / 100 * LEAST(pres_page."maxImageWidth" / pres_page."width", pres_page."maxImageHeight" / pres_page."height")) AS "scaledViewBoxWidth", - (pres_page."height" * pres_page."heightRatio" / 100 * LEAST(pres_page."maxImageWidth" / pres_page."width", pres_page."maxImageHeight" / pres_page."height")) AS "scaledViewBoxHeight" + (pres_page."height" * pres_page."heightRatio" / 100 * LEAST(pres_page."maxImageWidth" / pres_page."width", pres_page."maxImageHeight" / pres_page."height")) AS "scaledViewBoxHeight", + pres_page."infiniteWhiteboard" FROM pres_presentation JOIN pres_page ON pres_presentation."presentationId" = pres_page."presentationId" AND pres_page."current" IS TRUE and pres_presentation."current" IS TRUE; @@ -1558,12 +1525,10 @@ CREATE TABLE "timer" ( "time" bigint, "accumulated" bigint, "startedOn" bigint, - "endedOn" bigint, "songTrack" varchar(50) ); ALTER TABLE "timer" ADD COLUMN "startedAt" timestamp with time zone GENERATED ALWAYS AS (CASE WHEN "startedOn" = 0 THEN NULL ELSE to_timestamp("startedOn"::double precision / 1000) END) STORED; -ALTER TABLE "timer" ADD COLUMN "endedAt" timestamp with time zone GENERATED ALWAYS AS (CASE WHEN "endedOn" = 0 THEN NULL ELSE to_timestamp("endedOn"::double precision / 1000) END) STORED; CREATE OR REPLACE VIEW "v_timer" AS SELECT @@ -1571,15 +1536,14 @@ SELECT "stopwatch", case when "stopwatch" is true or "running" is false then "running" - when "startedAt" + (("time" - coalesce("accumulated",0)) * interval '1 milliseconds') >= current_timestamp then true else false + when "startedAt" + (("time" - coalesce("accumulated",0)) * interval '1 milliseconds') >= current_timestamp then true + else false end "running", "active", "time", "accumulated", "startedAt", "startedOn", - "endedAt", - "endedOn", "songTrack" FROM "timer"; @@ -1614,52 +1578,141 @@ CREATE TABLE "breakoutRoom_user" ( "assignedAt" timestamp with time zone, "joinedAt" timestamp with time zone, "inviteDismissedAt" timestamp with time zone, + "userJoinedSomeRoomAt" timestamp with time zone, + "isLastAssignedRoom" boolean, + "isLastJoinedRoom" boolean, + "isUserCurrentlyInRoom" boolean, CONSTRAINT "breakoutRoom_user_pkey" PRIMARY KEY ("breakoutRoomId", "meetingId", "userId"), FOREIGN KEY ("meetingId", "userId") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE ); create index "idx_breakoutRoom_user_meeting_user" on "breakoutRoom_user" ("meetingId", "userId"); create index "idx_breakoutRoom_user_user_meeting" on "breakoutRoom_user" ("userId", "meetingId"); +ALTER TABLE "breakoutRoom_user" ADD COLUMN "showInvitation" boolean GENERATED ALWAYS AS ( + CASE WHEN + "isLastAssignedRoom" IS true + and "isUserCurrentlyInRoom" is null + AND ("joinedAt" is null or "assignedAt" > "joinedAt") + AND ("userJoinedSomeRoomAt" is null or "assignedAt" > "userJoinedSomeRoomAt") + AND ("inviteDismissedAt" is null or "assignedAt" > "inviteDismissedAt") + THEN true + ELSE false + END) STORED; + --AND ("isModerator" is false OR "sendInvitationToModerators") + +--Trigger to populate `isLastAssignedRoom` and `isLastJoinedRoom` +CREATE OR REPLACE FUNCTION "ins_upd_del_breakoutRoom_user_trigger_func"() RETURNS TRIGGER AS $$ +BEGIN + IF TG_OP = 'DELETE' THEN + -- Determine the latest assigned room and latest joined room for the remaining rows + PERFORM + set_last_room(OLD."meetingId", OLD."userId"); + ELSE + -- For INSERT or UPDATE + PERFORM + set_last_room(NEW."meetingId", NEW."userId"); + END IF; + + RETURN NULL; +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION set_last_room(meetingId varchar(100), userId varchar(50)) RETURNS VOID AS $$ +DECLARE + "latestAssignedRoomId" varchar(100); + "latestJoinedRoomId" varchar(100); + "latestJoinedAt" timestamp with time zone; +BEGIN + SELECT "breakoutRoomId" + INTO "latestAssignedRoomId" + FROM "breakoutRoom_user" + WHERE "meetingId" = meetingId + AND "userId" = userId + AND "assignedAt" IS NOT NULL + ORDER BY "assignedAt" DESC NULLS LAST + LIMIT 1; + + SELECT "breakoutRoomId" + INTO "latestJoinedRoomId" + FROM "breakoutRoom_user" + WHERE "meetingId" = meetingId + AND "userId" = userId + AND "joinedAt" IS NOT NULL + ORDER BY "joinedAt" DESC NULLS LAST + LIMIT 1; + + UPDATE "breakoutRoom_user" bu + SET "isLastAssignedRoom" = CASE + WHEN "latestAssignedRoomId" IS NOT NULL AND bu."breakoutRoomId" = "latestAssignedRoomId" THEN TRUE + ELSE FALSE + END, + "isLastJoinedRoom" = CASE + WHEN "latestJoinedRoomId" IS NOT NULL AND bu."breakoutRoomId" = "latestJoinedRoomId" THEN TRUE + ELSE FALSE + END + WHERE bu."meetingId" = meetingId + AND bu."userId" = userId + AND (bu."isLastAssignedRoom" IS DISTINCT FROM (CASE WHEN "latestAssignedRoomId" IS NOT NULL AND bu."breakoutRoomId" = "latestAssignedRoomId" THEN TRUE ELSE FALSE END) + OR bu."isLastJoinedRoom" IS DISTINCT FROM (CASE WHEN "latestJoinedRoomId" IS NOT NULL AND bu."breakoutRoomId" = "latestJoinedRoomId" THEN TRUE ELSE FALSE END)); + + --userJoinedSomeRoomAt + SELECT max("joinedAt") + INTO "latestJoinedAt" + from "breakoutRoom_user" bru + where bru."meetingId" = meetingId + and bru."userId" = userId; + + update "breakoutRoom_user" set "userJoinedSomeRoomAt" = "latestJoinedAt" + where "breakoutRoom_user"."meetingId" = meetingId + and "breakoutRoom_user"."userId" = userId + and "breakoutRoom_user"."userJoinedSomeRoomAt" != "latestJoinedAt"; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER "ins_upd_del_breakoutRoom_user_trigger" +AFTER INSERT OR UPDATE OR DELETE ON "breakoutRoom_user" +FOR EACH ROW EXECUTE FUNCTION "ins_upd_del_breakoutRoom_user_trigger_func"(); + + +CREATE OR REPLACE FUNCTION "update_bkroom_isUserCurrentlyInRoom_trigger_func"() +RETURNS TRIGGER AS $$ +BEGIN + IF NEW."currentlyInMeeting" <> OLD."currentlyInMeeting" THEN + update "breakoutRoom_user" set "isUserCurrentlyInRoom" = a."currentlyInMeeting" + from ( + select + bru."breakoutRoomId", bru."userId", bkroom_user."currentlyInMeeting" + from "user" bkroom_user + join meeting_breakout mb on mb."meetingId" = bkroom_user."meetingId" + join "breakoutRoom" br on br."parentMeetingId" = mb."parentId" and mb."sequence" = br."sequence" + join "user" u on u."meetingId" = br."parentMeetingId" and bkroom_user."extId" = u."extId" || '-' || br."sequence" + join "breakoutRoom_user" bru on bru."userId" = u."userId" and bru."breakoutRoomId" = br."breakoutRoomId" + where bkroom_user."userId" = NEW."userId" + ) a + where "breakoutRoom_user"."breakoutRoomId" = a."breakoutRoomId" + and "breakoutRoom_user"."userId" = a."userId"; + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER "update_bkroom_isUserCurrentlyInRoom_trigger" AFTER UPDATE OF "currentlyInMeeting" ON "user" + FOR EACH ROW EXECUTE FUNCTION "update_bkroom_isUserCurrentlyInRoom_trigger_func"(); CREATE OR REPLACE VIEW "v_breakoutRoom" AS -SELECT *, - --showInvitation flag - case WHEN 1=1 - --this is not the last room the user joined - -- AND "lastRoomJoinedId" != "breakoutRoomId" --the next condition turn this one useless - --user didn't joined some room after assigned - AND ("lastRoomJoinedAt" IS NULL OR "lastRoomJoinedAt" < "assignedAt") - --user didn't close the invitation already - and ("inviteDismissedAt" is NULL OR "assignedAt" > "inviteDismissedAt") - --user is not online in other room - AND "lastRoomIsOnline" IS FALSE - --this is this the last assignment? - AND "currentRoomPriority" = 1 - --user is not moderator or sendInviteToMod flag is true - AND ("isModerator" is false OR "sendInvitationToModerators") - THEN TRUE ELSE FALSE END "showInvitation" -from ( - SELECT u."meetingId" as "userMeetingId", u."userId", b."parentMeetingId", b."breakoutRoomId", b."freeJoin", b."sequence", b."name", b."isDefaultName", +SELECT u."meetingId" as "userMeetingId", u."userId", b."parentMeetingId", b."breakoutRoomId", b."freeJoin", + b."sequence", b."name", b."isDefaultName", b."shortName", b."startedAt", b."endedAt", b."durationInSeconds", b."sendInvitationToModerators", - bu."assignedAt", bu."joinURL", bu."inviteDismissedAt", u."role" = 'MODERATOR' as "isModerator", - --CASE WHEN b."durationInSeconds" = 0 THEN NULL ELSE b."startedAt" + b."durationInSeconds" * '1 second'::INTERVAL END AS "willEndAt", - ub."isOnline" AS "currentRoomIsOnline", - ub."registeredAt" AS "currentRoomRegisteredAt", - ub."joined" AS "currentRoomJoined", - rank() OVER (partition BY u."meetingId", u."userId" order by "assignedAt" desc nulls last) as "currentRoomPriority", - max(bu."joinedAt") OVER (partition BY u."meetingId", u."userId") AS "lastRoomJoinedAt", - max(bu."breakoutRoomId") OVER (partition BY u."meetingId", u."userId" ORDER BY bu."joinedAt") AS "lastRoomJoinedId", - sum(CASE WHEN ub."isOnline" THEN 1 ELSE 0 END) OVER (partition BY u."meetingId", u."userId") > 0 as "lastRoomIsOnline" + bu."assignedAt", bu."joinURL", bu."inviteDismissedAt", u."role" = 'MODERATOR' as "isModerator", + bu."isLastAssignedRoom", bu."isLastJoinedRoom", bu."isUserCurrentlyInRoom", bu."showInvitation", + bu."joinedAt" is not null as "hasJoined" FROM "user" u JOIN "breakoutRoom" b ON b."parentMeetingId" = u."meetingId" LEFT JOIN "breakoutRoom_user" bu ON bu."meetingId" = u."meetingId" AND bu."userId" = u."userId" AND bu."breakoutRoomId" = b."breakoutRoomId" - LEFT JOIN "meeting" mb ON mb."extId" = b."externalId" - LEFT JOIN "v_user" ub ON ub."meetingId" = mb."meetingId" and ub."extId" = u."extId" || '-' || b."sequence" WHERE (bu."assignedAt" IS NOT NULL OR b."freeJoin" IS TRUE OR u."role" = 'MODERATOR') - AND b."endedAt" IS NULL -) a; + AND b."endedAt" IS NULL; CREATE OR REPLACE VIEW "v_breakoutRoom_assignedUser" AS SELECT "parentMeetingId", "breakoutRoomId", "userMeetingId", "userId" @@ -1675,7 +1728,7 @@ SELECT DISTINCT "userId", false as "isAudioOnly" FROM "v_breakoutRoom" -WHERE "currentRoomIsOnline" IS TRUE +WHERE "isUserCurrentlyInRoom" IS TRUE union --include users that joined only with audio select parent_user."meetingId" as "parentMeetingId", bk_user."meetingId" as "breakoutRoomId", @@ -1771,17 +1824,17 @@ SELECT FLOOR(EXTRACT(EPOCH FROM current_timestamp) * 1000)::bigint AS "currentTimeMillis"; ------------------------------------ -----audioCaption or typedCaption +----caption CREATE TABLE "caption_locale" ( "meetingId" varchar(100) NOT NULL REFERENCES "meeting"("meetingId") ON DELETE CASCADE, "locale" varchar(15) NOT NULL, "captionType" varchar(100) NOT NULL, --Audio Transcription or Typed Caption - "ownerUserId" varchar(50), + "createdBy" varchar(50), "createdAt" timestamp with time zone default current_timestamp, "updatedAt" timestamp with time zone, CONSTRAINT "caption_locale_pk" primary key ("meetingId","locale","captionType"), - FOREIGN KEY ("meetingId", "ownerUserId") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE + FOREIGN KEY ("meetingId", "createdBy") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE ); create index "idx_caption_locale_pk_reverse" on "caption_locale"("locale","meetingId","captionType"); create index "idx_caption_locale_pk_reverse_b" on "caption_locale"("captionType","meetingId","locale"); @@ -1802,11 +1855,11 @@ CREATE OR REPLACE FUNCTION "update_caption_locale_owner_func"() RETURNS TRIGGER BEGIN WITH upsert AS ( UPDATE "caption_locale" SET - "ownerUserId" = NEW."userId", + "createdBy" = NEW."userId", "updatedAt" = current_timestamp WHERE "meetingId"=NEW."meetingId" AND "locale"=NEW."locale" AND "captionType"= NEW."captionType" RETURNING *) - INSERT INTO "caption_locale"("meetingId","locale","captionType","ownerUserId") + INSERT INTO "caption_locale"("meetingId","locale","captionType","createdBy") SELECT NEW."meetingId", NEW."locale", NEW."captionType", NEW."userId" WHERE NOT EXISTS (SELECT * FROM upsert); @@ -1826,7 +1879,7 @@ FROM "caption" WHERE "createdAt" > current_timestamp - INTERVAL '5 seconds'; CREATE OR REPLACE VIEW "v_caption_activeLocales" AS -select distinct "meetingId", "locale", "ownerUserId", "captionType" +select distinct "meetingId", "locale", "createdBy", "captionType" from "caption_locale"; create index "idx_caption_typed_activeLocales" on "caption"("meetingId","locale","userId") where "captionType" = 'TYPED'; @@ -1905,13 +1958,13 @@ CREATE TABLE "pluginDataChannelEntry" ( "entryId" varchar(50) DEFAULT uuid_generate_v4(), "subChannelName" varchar(255), "payloadJson" jsonb, - "fromUserId" varchar(50), + "createdBy" varchar(50), "toRoles" varchar[], --MODERATOR, VIEWER, PRESENTER "toUserIds" varchar[], "createdAt" timestamp with time zone DEFAULT current_timestamp, "deletedAt" timestamp with time zone, CONSTRAINT "pluginDataChannel_pkey" PRIMARY KEY ("meetingId","pluginName","channelName","entryId", "subChannelName"), - FOREIGN KEY ("meetingId", "fromUserId") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE + FOREIGN KEY ("meetingId", "createdBy") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE ); create index "idx_pluginDataChannelEntry_pk_reverse" on "pluginDataChannelEntry"("pluginName", "meetingId", "channelName", "subChannelName"); create index "idx_pluginDataChannelEntry_pk_reverse_b" on "pluginDataChannelEntry"("channelName", "pluginName", "meetingId", "subChannelName"); @@ -1920,7 +1973,7 @@ create index "idx_pluginDataChannelEntry_channelName" on "pluginDataChannelEntry create index "idx_pluginDataChannelEntry_roles" on "pluginDataChannelEntry"("meetingId", "toRoles", "toUserIds", "createdAt") where "deletedAt" is null; CREATE OR REPLACE VIEW "v_pluginDataChannelEntry" AS -SELECT u."meetingId", u."userId", m."pluginName", m."channelName", m."subChannelName", m."entryId", m."payloadJson", m."fromUserId", m."toRoles", m."createdAt" +SELECT u."meetingId", u."userId", m."pluginName", m."channelName", m."subChannelName", m."entryId", m."payloadJson", m."createdBy", m."toRoles", m."createdAt" FROM "user" u JOIN "pluginDataChannelEntry" m ON m."meetingId" = u."meetingId" AND ((m."toRoles" IS NULL AND m."toUserIds" IS NULL) @@ -1964,7 +2017,14 @@ select "meeting"."meetingId", select 1 from "v_screenshare" where "v_screenshare"."meetingId" = "meeting"."meetingId" + and "contentType" = 'screenshare' ) as "hasScreenshare", + exists ( + select 1 + from "v_screenshare" + where "v_screenshare"."meetingId" = "meeting"."meetingId" + and "contentType" = 'camera' + ) as "hasCameraAsContent", exists ( select 1 from "v_externalVideo" @@ -1972,13 +2032,7 @@ select "meeting"."meetingId", ) as "hasExternalVideo", exists ( select 1 - from "v_user" - where "v_user"."meetingId" = "meeting"."meetingId" - and NULLIF("speechLocale",'') is not null - ) or exists ( - select 1 - from "sharedNotes" - where "sharedNotes"."meetingId" = "meeting"."meetingId" - and "model" = 'captions' + from "v_caption_activeLocales" + where "v_caption_activeLocales"."meetingId" = "meeting"."meetingId" ) as "hasCaption" from "meeting"; diff --git a/bbb-graphql-server/deploy.sh b/bbb-graphql-server/deploy.sh new file mode 100755 index 0000000000..0667b7f1b1 --- /dev/null +++ b/bbb-graphql-server/deploy.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +cd "$(dirname "$0")" + +export LANGUAGE="en_US.UTF-8" +export LC_ALL="en_US.UTF-8" + +akka_apps_status=$(sudo systemctl is-active "bbb-apps-akka") +hasura_status=$(sudo systemctl is-active "bbb-graphql-server") + +if [ "$akka_apps_status" = "active" ]; then + echo "Stopping Akka-apps" + sudo systemctl stop bbb-apps-akka +fi +if [ "$hasura_status" = "active" ]; then + echo "Stopping Hasura" + sudo systemctl stop bbb-graphql-server +fi + +echo "Restarting database bbb_graphql" +sudo runuser -u postgres -- psql -q -c "drop database if exists bbb_graphql with (force)" +sudo runuser -u postgres -- psql -q -c "create database bbb_graphql WITH TEMPLATE template0 LC_COLLATE 'C.UTF-8'" +sudo runuser -u postgres -- psql -q -c "alter database bbb_graphql set timezone to 'UTC'" + +echo "Creating tables in bbb_graphql" +sudo runuser -u postgres -- psql -U postgres -d bbb_graphql -q -f bbb_schema.sql --set ON_ERROR_STOP=on + +echo "Starting Hasura" +sudo systemctl start bbb-graphql-server + +#Check if Hasura is ready before applying metadata +HASURA_PORT=8085 +while ! sudo netstat -tuln | grep ":$HASURA_PORT " > /dev/null; do + echo "Waiting for Hasura's port ($HASURA_PORT) to be ready..." + sleep 1 +done + +if [ "$akka_apps_status" = "active" ]; then + echo "Starting Akka-apps" + sudo systemctl start bbb-apps-akka +fi + +echo "Applying new metadata to Hasura" +timeout 15s sudo hasura metadata apply --skip-update-check diff --git a/bbb-graphql-server/install-hasura.sh b/bbb-graphql-server/install-hasura.sh deleted file mode 100755 index 4353c3a4a9..0000000000 --- a/bbb-graphql-server/install-hasura.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash -if [ "$EUID" -ne 0 ]; then - echo "Please run this script as root ( or with sudo )" ; - exit 1; -fi; - -cd "$(dirname "$0")" - - -# Install Postgresql -apt update -apt install postgresql postgresql-contrib -y -runuser -u postgres -- psql -c "alter user postgres password 'bbb_graphql'" -runuser -u postgres -- psql -c "drop database if exists bbb_graphql with (force)" -runuser -u postgres -- psql -c "create database bbb_graphql WITH TEMPLATE template0 LC_COLLATE 'C.UTF-8'" -runuser -u postgres -- psql -c "alter database bbb_graphql set timezone to 'UTC'" -runuser -u postgres -- psql -U postgres -d bbb_graphql -a -f bbb_schema.sql --set ON_ERROR_STOP=on -runuser -u postgres -- psql -c "drop database if exists hasura_app with (force)" -runuser -u postgres -- psql -c "create database hasura_app" - -echo "Creating frontend in bbb_graphql" -DATABASE_FRONTEND_USER="bbb_frontend" -FRONT_USER_EXISTS=$(sudo -u postgres psql -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname = '$DATABASE_FRONTEND_USER'") -if [ "$FRONT_USER_EXISTS" = '1' ] -then - echo "User $DATABASE_FRONTEND_USER already exists" -else - sudo -u postgres psql -q -c "CREATE USER $DATABASE_FRONTEND_USER WITH PASSWORD '$DATABASE_FRONTEND_USER'" - sudo -u postgres psql -q -c "GRANT CONNECT ON DATABASE bbb_graphql TO $DATABASE_FRONTEND_USER" - sudo -u postgres psql -q -d bbb_graphql -c "REVOKE ALL ON ALL TABLES IN SCHEMA public FROM $DATABASE_FRONTEND_USER" - sudo -u postgres psql -q -d bbb_graphql -c "GRANT USAGE ON SCHEMA public TO $DATABASE_FRONTEND_USER" - echo "User $DATABASE_FRONTEND_USER created on database bbb_graphql" -fi - -sudo -u postgres psql -q -d bbb_graphql -c "GRANT SELECT ON v_user_connection_auth TO $DATABASE_FRONTEND_USER" - -echo "Postgresql installed!" - - -#Build Hasura -# https://github.com/hasura/graphql-engine/blob/master/server/CONTRIBUTING.md -# sudo apt install haskell-platform -y -# sudo apt-get install cabal-install -y -#wget https://golang.org/dl/go1.16.3.linux-amd64.tar.gz -#sudo sh -c "rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.3.linux-amd64.tar.gz" -#export PATH=$PATH:/usr/local/go/bin -#go version - -# Configs nginx -cp ./graphql.nginx /usr/share/bigbluebutton/nginx -systemctl restart nginx - -# Install Hasura graphql as service -#wget https://graphql-engine-cdn.hasura.io/server/latest/linux-amd64 -O /usr/local/bin/hasura-graphql-engine -#chmod +x /usr/local/bin/hasura-graphql-engine - -#Hasura 2.29+ requires Ubuntu 22 -git clone --branch v2.37.0 https://github.com/iMDT/hasura-graphql-engine.git -cat hasura-graphql-engine/hasura-graphql.part-a* > hasura-graphql -rm -rf hasura-graphql-engine/ -chmod +x hasura-graphql -mv hasura-graphql /usr/local/bin/hasura-graphql-engine - -apt-get install -y gnupg2 curl apt-transport-https ca-certificates libkrb5-3 libpq5 libnuma1 unixodbc-dev -cp ./hasura-config.env /etc/default/bbb-graphql-server -#Enable Console --Desenv only!! -sudo sed -i 's/HASURA_GRAPHQL_ENABLE_CONSOLE=false/HASURA_GRAPHQL_ENABLE_CONSOLE=true/' /etc/default/bbb-graphql-server - -cp ./bbb-graphql-server.service /lib/systemd/system/bbb-graphql-server.service -systemctl enable bbb-graphql-server -systemctl start bbb-graphql-server - -# Install Hasura CLI -curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | bash - -# Apply BBB metadata in Hasura -hasura metadata apply --skip-update-check - -echo "" -echo "" -echo "Bbb-graphql-server Installed!" -echo "http://$(hostname -f):8085/console" diff --git a/bbb-graphql-server/metadata/actions.graphql b/bbb-graphql-server/metadata/actions.graphql index f1d232c9a9..76140ddde4 100644 --- a/bbb-graphql-server/metadata/actions.graphql +++ b/bbb-graphql-server/metadata/actions.graphql @@ -41,6 +41,10 @@ type Mutation { ): Boolean } +type Mutation { + breakoutRoomSetInviteDismissed: Boolean +} + type Mutation { breakoutRoomSetTime( timeInMinutes: Int! @@ -60,9 +64,8 @@ type Mutation { } type Mutation { - captionSetOwner( + captionAddLocale( locale: String! - ownerUserId: String! ): Boolean } @@ -78,6 +81,14 @@ type Mutation { ): Boolean } +type Mutation { + captionSubmitTranscript( + transcriptId: String! + transcript: String! + locale: String! + ): Boolean +} + type Mutation { chatCreateWithUser( userId: String! @@ -98,15 +109,30 @@ type Mutation { chatSendMessage( chatId: String! chatMessageInMarkdownFormat: String! + metadata: json ): Boolean } +type Mutation { + chatSetLastSeen: Boolean +} + type Mutation { chatSetTyping( chatId: String ): Boolean } +type Mutation { + chatSetVisible( + visible: Boolean! + ): Boolean +} + +type Mutation { + echoTestRunningAt: Boolean +} + type Mutation { externalVideoStart( externalVideoUrl: String! @@ -227,6 +253,16 @@ type Mutation { ): Boolean } +type Mutation { + pluginDataChannelReplaceEntry( + pluginName: String! + subChannelName: String! + channelName: String! + entryId: String! + payloadJson: String! + ): Boolean +} + type Mutation { pluginDataChannelReset( pluginName: String! @@ -235,6 +271,13 @@ type Mutation { ): Boolean } +type Mutation { + pluginLearningAnalyticsDashboardSendGenericData( + genericDataForLearningAnalyticsDashboard: json! + pluginName: String! + ): Boolean +} + type Mutation { pollCancel: Boolean } @@ -340,6 +383,13 @@ type Mutation { ): Boolean } +type Mutation { + presentationSetPageInfiniteWhiteboard( + infiniteWhiteboard: Boolean! + pageId: String! + ): Boolean +} + type Mutation { presentationSetRenderedInToast( presentationId: String! @@ -469,6 +519,19 @@ type Mutation { ): Boolean } +type Mutation { + userSetCaptionLocale( + locale: String! + provider: String! + ): Boolean +} + +type Mutation { + userSetClientSettings( + userClientSettingsJson: json! + ): Boolean +} + type Mutation { userSetConnectionAlive( networkRttInMs: Float! @@ -494,12 +557,6 @@ type Mutation { ): Boolean } -type Mutation { - userSetMobileFlag( - mobile: Boolean! - ): Boolean -} - type Mutation { userSetMuted( userId: String @@ -540,6 +597,13 @@ type Mutation { ): Boolean } +type Mutation { + userSetSpeechOptions( + partialUtterances: Boolean! + minUtteranceLength: Float! + ): Boolean +} + type Mutation { userThirdPartyInfoResquest( externalUserId: String! diff --git a/bbb-graphql-server/metadata/actions.yaml b/bbb-graphql-server/metadata/actions.yaml index 36a41463ce..48edf32ae8 100644 --- a/bbb-graphql-server/metadata/actions.yaml +++ b/bbb-graphql-server/metadata/actions.yaml @@ -41,6 +41,12 @@ actions: handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client + - name: breakoutRoomSetInviteDismissed + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client - name: breakoutRoomSetTime definition: kind: synchronous @@ -59,7 +65,7 @@ actions: handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client - - name: captionSetOwner + - name: captionAddLocale definition: kind: synchronous handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' @@ -71,6 +77,12 @@ actions: handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client + - name: captionSubmitTranscript + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client - name: chatCreateWithUser definition: kind: synchronous @@ -95,12 +107,30 @@ actions: handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client + - name: chatSetLastSeen + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client - name: chatSetTyping definition: kind: synchronous handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client + - name: chatSetVisible + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client + - name: echoTestRunningAt + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client - name: externalVideoStart definition: kind: synchronous @@ -197,12 +227,24 @@ actions: handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client + - name: pluginDataChannelReplaceEntry + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client - name: pluginDataChannelReset definition: kind: synchronous handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client + - name: pluginLearningAnalyticsDashboardSendGenericData + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client - name: pollCancel definition: kind: synchronous @@ -294,6 +336,12 @@ actions: handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client + - name: presentationSetPageInfiniteWhiteboard + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client - name: presentationSetRenderedInToast definition: kind: synchronous @@ -395,7 +443,7 @@ actions: kind: synchronous handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - - role: not_joined_bbb_client + - role: bbb_client_not_in_meeting - role: bbb_client - name: userLeaveMeeting definition: @@ -421,6 +469,18 @@ actions: handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client + - name: userSetCaptionLocale + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client + - name: userSetClientSettings + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client - name: userSetConnectionAlive definition: kind: synchronous @@ -445,12 +505,6 @@ actions: handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client - - name: userSetMobileFlag - definition: - kind: synchronous - handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' - permissions: - - role: bbb_client - name: userSetMuted definition: kind: synchronous @@ -487,6 +541,12 @@ actions: handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' permissions: - role: bbb_client + - name: userSetSpeechOptions + definition: + kind: synchronous + handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}' + permissions: + - role: bbb_client - name: userThirdPartyInfoResquest definition: kind: synchronous diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_breakoutRoom.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_breakoutRoom.yaml index 8767ea82df..0f3ae1ed19 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_breakoutRoom.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_breakoutRoom.yaml @@ -31,19 +31,15 @@ select_permissions: columns: - assignedAt - breakoutRoomId - - currentRoomIsOnline - - currentRoomJoined - - currentRoomPriority - - currentRoomRegisteredAt + - isUserCurrentlyInRoom + - hasJoined + - isLastAssignedRoom - durationInSeconds - endedAt - freeJoin - inviteDismissedAt - isDefaultName - joinURL - - lastRoomIsOnline - - lastRoomJoinedAt - - lastRoomJoinedId - name - sendInvitationToModerators - sequence diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_breakoutRoom_user.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_breakoutRoom_user.yaml index d3da44708e..26d75ada0d 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_breakoutRoom_user.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_breakoutRoom_user.yaml @@ -22,16 +22,3 @@ select_permissions: - userId: _eq: X-Hasura-UserId comment: "" -update_permissions: - - role: bbb_client - permission: - columns: - - inviteDismissedAt - filter: - _and: - - meetingId: - _eq: X-Hasura-MeetingId - - userId: - _eq: X-Hasura-UserId - check: null - comment: "" diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_caption_activeLocales.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_caption_activeLocales.yaml index e66d709192..ae7197a75c 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_caption_activeLocales.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_caption_activeLocales.yaml @@ -11,8 +11,8 @@ object_relationships: using: manual_configuration: column_mapping: + createdBy: userId meetingId: meetingId - ownerUserId: userId insertion_order: null remote_table: name: v_user_ref diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_private.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_private.yaml index e86e0b0d42..fa991fbdcc 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_private.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_message_private.yaml @@ -32,6 +32,7 @@ select_permissions: - senderId - senderName - senderRole + - recipientHasSeen filter: _and: - meetingId: diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_user.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_user.yaml index ba32edbfaa..a1761430ab 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_user.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_chat_user.yaml @@ -32,22 +32,3 @@ select_permissions: _eq: X-Hasura-MeetingId - userId: _eq: X-Hasura-UserId -update_permissions: - - role: bbb_client - permission: - columns: - - lastSeenAt - - lastTypingAt - - visible - filter: - _and: - - meetingId: - _eq: X-Hasura-MeetingId - - userId: - _eq: X-Hasura-UserId - - visible: - _eq: true - check: {} - set: - meetingId: x-hasura-MeetingId - userId: x-hasura-UserId diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting.yaml index e7868c3508..9b2a5fdf51 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting.yaml @@ -161,6 +161,7 @@ select_permissions: - createdAt - createdTime - customLogoUrl + - customDarkLogoUrl - disabledFeatures - durationInSeconds - endWhenNoModerator @@ -184,12 +185,13 @@ select_permissions: filter: meetingId: _eq: X-Hasura-MeetingId - - role: not_joined_bbb_client + - role: bbb_client_not_in_meeting permission: columns: - bannerColor - bannerText - customLogoUrl + - customDarkLogoUrl - ended - endedAt - endedBy diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_clientSettings.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_clientSettings.yaml index d1e095d77b..002895c02c 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_clientSettings.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_clientSettings.yaml @@ -15,7 +15,7 @@ select_permissions: meetingId: _eq: X-Hasura-MeetingId comment: "" - - role: not_joined_bbb_client + - role: bbb_client_not_in_meeting permission: columns: - clientSettingsJson diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_componentsFlags.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_componentsFlags.yaml index cddaf4ca19..8925ea7141 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_componentsFlags.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_componentsFlags.yaml @@ -15,6 +15,7 @@ select_permissions: - hasExternalVideo - hasPoll - hasScreenshare + - hasCameraAsContent - hasTimer - showRemainingTime filter: diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_learningDashboard.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_learningDashboard.yaml index fa75535828..e401118508 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_learningDashboard.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_meeting_learningDashboard.yaml @@ -10,7 +10,7 @@ select_permissions: meetingId: _eq: X-Hasura-ModeratorInMeeting comment: "" - - role: not_joined_bbb_client + - role: bbb_client_not_in_meeting permission: columns: - learningDashboardAccessToken diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pluginDataChannelEntry.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pluginDataChannelEntry.yaml index 50723d0084..c21c618b72 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pluginDataChannelEntry.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pluginDataChannelEntry.yaml @@ -7,11 +7,11 @@ configuration: custom_name: pluginDataChannelEntry custom_root_fields: {} object_relationships: - - name: sender + - name: creator using: manual_configuration: column_mapping: - fromUserId: userId + createdBy: userId meetingId: meetingId insertion_order: null remote_table: @@ -27,7 +27,7 @@ select_permissions: - channelName - entryId - payloadJson - - fromUserId + - createdBy - toRoles filter: _and: diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page.yaml index ddbf350ab5..27858f4db7 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page.yaml @@ -39,6 +39,7 @@ select_permissions: - widthRatio - xOffset - yOffset + - infiniteWhiteboard filter: meetingId: _eq: X-Hasura-PresenterInMeeting diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page_curr.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page_curr.yaml index 3cab393855..ad21044261 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page_curr.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_pres_page_curr.yaml @@ -37,6 +37,7 @@ select_permissions: - widthRatio - xOffset - yOffset + - infiniteWhiteboard filter: meetingId: _eq: X-Hasura-MeetingId diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_timer.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_timer.yaml index 1493cd42c4..356d799840 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_timer.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_timer.yaml @@ -12,8 +12,6 @@ select_permissions: columns: - accumulated - active - - endedAt - - endedOn - running - songTrack - startedAt diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user.yaml index 60e500891e..9276e5fbed 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user.yaml @@ -34,15 +34,6 @@ object_relationships: remote_table: name: v_meeting schema: public - - name: reaction - using: - manual_configuration: - column_mapping: - userId: userId - insertion_order: null - remote_table: - name: v_user_reaction_current - schema: public - name: voice using: manual_configuration: @@ -81,11 +72,10 @@ select_permissions: - away - awayTime - banned + - captionLocale - clientType - color - disconnected - - emoji - - emojiTime - expired - extId - guest @@ -93,7 +83,7 @@ select_permissions: - hasDrawPermissionOnCurrentPage - isDialIn - isModerator - - isOnline + - currentlyInMeeting - isRunningEchoTest - joined - locked @@ -105,6 +95,8 @@ select_permissions: - presenter - raiseHand - raiseHandTime + - reactionEmoji + - registeredAt - registeredOn - role - speechLocale diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_clientSettings.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_clientSettings.yaml index 87b908a39b..85f53ffafc 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_clientSettings.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_clientSettings.yaml @@ -18,18 +18,3 @@ select_permissions: _eq: X-Hasura-MeetingId - userId: _eq: X-Hasura-UserId -update_permissions: - - role: bbb_client - permission: - columns: - - userClientSettingsJson - filter: - _and: - - meetingId: - _eq: X-Hasura-MeetingId - - userId: - _eq: X-Hasura-UserId - check: {} - set: - meetingId: x-hasura-MeetingId - userId: x-hasura-UserId diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_current.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_current.yaml index ddb7e86aee..c7d5bd20b4 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_current.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_current.yaml @@ -16,15 +16,6 @@ object_relationships: remote_table: name: v_user_connectionStatus schema: public - - name: customParameters - using: - manual_configuration: - column_mapping: - userId: userId - insertion_order: null - remote_table: - name: v_user_customParameter - schema: public - name: guestStatusDetails using: manual_configuration: @@ -52,15 +43,6 @@ object_relationships: remote_table: name: v_meeting schema: public - - name: reaction - using: - manual_configuration: - column_mapping: - userId: userId - insertion_order: null - remote_table: - name: v_user_reaction_current - schema: public - name: sharedNotesSession using: manual_configuration: @@ -88,6 +70,15 @@ object_relationships: remote_table: name: v_user_clientSettings schema: public + - name: userMetadata + using: + manual_configuration: + column_mapping: + userId: userId + insertion_order: null + remote_table: + name: v_user_metadata + schema: public - name: voice using: manual_configuration: @@ -97,6 +88,15 @@ object_relationships: remote_table: name: v_user_voice schema: public + - name: welcomeMsgs + using: + manual_configuration: + column_mapping: + userId: userId + insertion_order: null + remote_table: + name: v_user_welcomeMsgs + schema: public array_relationships: - name: breakoutRooms using: @@ -142,25 +142,28 @@ select_permissions: - authToken - authed - avatar + - webcamBackground - away - banned + - captionLocale - clientType - - enforceLayout - color - disconnected - echoTestRunningAt - ejectReason - ejectReasonCode - ejected - - emoji + - enforceLayout - expired - extId - guest - guestStatus - hasDrawPermissionOnCurrentPage + - inactivityWarningDisplay + - inactivityWarningTimeoutSecs - isDialIn - isModerator - - isOnline + - currentlyInMeeting - isRunningEchoTest - joinErrorCode - joinErrorMessage @@ -173,12 +176,11 @@ select_permissions: - pinned - presenter - raiseHand + - reactionEmoji - registeredAt - registeredOn - role - speechLocale - - inactivityWarningDisplay - - inactivityWarningTimeoutSecs - userId filter: _and: @@ -186,7 +188,7 @@ select_permissions: _eq: X-Hasura-MeetingId - userId: _eq: X-Hasura-UserId - - role: not_joined_bbb_client + - role: bbb_client_not_in_meeting permission: columns: - authToken @@ -198,7 +200,7 @@ select_permissions: - ejectReasonCode - ejected - expired - - isOnline + - currentlyInMeeting - isModerator - extId - guest @@ -218,15 +220,3 @@ select_permissions: - userId: _eq: X-Hasura-UserId comment: "" -update_permissions: - - role: bbb_client - permission: - columns: - - echoTestRunningAt - filter: - _and: - - meetingId: - _eq: X-Hasura-MeetingId - - userId: - _eq: X-Hasura-UserId - check: null diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_guest.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_guest.yaml index 70a0a7252f..e961b0e20b 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_guest.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_guest.yaml @@ -37,11 +37,12 @@ select_permissions: - meetingId: _eq: X-Hasura-ModeratorInMeeting allow_aggregations: true - - role: not_joined_bbb_client + - role: bbb_client_not_in_meeting permission: columns: - guestLobbyMessage - guestStatus + - isAllowed - positionInWaitingQueue filter: _and: diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_customParameter.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_metadata.yaml similarity index 84% rename from bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_customParameter.yaml rename to bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_metadata.yaml index 93fd1fc1b2..7e63486977 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_customParameter.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_metadata.yaml @@ -1,10 +1,10 @@ table: - name: v_user_customParameter + name: v_user_metadata schema: public configuration: column_config: {} custom_column_names: {} - custom_name: user_customParameter + custom_name: user_metadata custom_root_fields: {} select_permissions: - role: bbb_client diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_ref.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_ref.yaml index 6034a99b41..472c6136d0 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_ref.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_ref.yaml @@ -14,10 +14,10 @@ select_permissions: - avatar - away - banned + - captionLocale - clientType - color - disconnected - - emoji - expired - extId - guest @@ -25,7 +25,7 @@ select_permissions: - hasDrawPermissionOnCurrentPage - isDialIn - isModerator - - isOnline + - currentlyInMeeting - joined - locked - loggedOut @@ -35,6 +35,7 @@ select_permissions: - pinned - presenter - raiseHand + - reactionEmoji - registeredOn - role - speechLocale diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice.yaml index c7d3cace29..bf2f596387 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice.yaml @@ -27,10 +27,8 @@ select_permissions: - floor - joined - lastFloorTime - - lastSpeakChangedAt - listenOnly - muted - - showTalkingIndicator - spoke - startTime - talking diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice_activity.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice_activity.yaml new file mode 100644 index 0000000000..7d3e76bd5b --- /dev/null +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice_activity.yaml @@ -0,0 +1,33 @@ +table: + name: v_user_voice_activity + schema: public +configuration: + column_config: {} + custom_column_names: {} + custom_name: user_voice_activity + custom_root_fields: {} +object_relationships: + - name: user + using: + manual_configuration: + column_mapping: + meetingId: meetingId + userId: userId + insertion_order: null + remote_table: + name: v_user_ref + schema: public +select_permissions: + - role: bbb_client + permission: + columns: + - endTime + - muted + - startTime + - talking + - userId + - voiceActivityAt + filter: + meetingId: + _eq: X-Hasura-MeetingId + comment: "" diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice_mongodb_adapter.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice_mongodb_adapter.yaml deleted file mode 100644 index 06413f03d7..0000000000 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/public_v_user_voice_mongodb_adapter.yaml +++ /dev/null @@ -1,40 +0,0 @@ -table: - name: v_user_voice_mongodb_adapter - schema: public -configuration: - column_config: {} - custom_column_names: {} - custom_name: user_voice_mongodb_adapter - custom_root_fields: {} -select_permissions: - - role: bbb_client - permission: - columns: - - callerName - - callerNum - - callingWith - - endTime - - endedAt - - floor - - hideTalkingIndicatorAt - - joined - - lastFloorTime - - lastSpeakChangedAt - - listenOnly - - muted - - showTalkingIndicator - - spoke - - startTime - - startedAt - - talking - - userId - - voiceConf - - voiceConfCallSession - - voiceConfCallState - - voiceConfClientSession - - voiceUpdatedAt - - voiceUserId - filter: - meetingId: - _eq: X-Hasura-MeetingId - comment: "" diff --git a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml index a83d9ca3fa..cc285902d5 100644 --- a/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml +++ b/bbb-graphql-server/metadata/databases/BigBlueButton/tables/tables.yaml @@ -51,14 +51,13 @@ - "!include public_v_user_connectionStatus.yaml" - "!include public_v_user_connectionStatusReport.yaml" - "!include public_v_user_current.yaml" -- "!include public_v_user_customParameter.yaml" - "!include public_v_user_guest.yaml" +- "!include public_v_user_metadata.yaml" - "!include public_v_user_reaction.yaml" -- "!include public_v_user_reaction_current.yaml" - "!include public_v_user_ref.yaml" - "!include public_v_user_transcriptionError.yaml" - "!include public_v_user_typing_private.yaml" - "!include public_v_user_typing_public.yaml" - "!include public_v_user_voice.yaml" -- "!include public_v_user_voice_mongodb_adapter.yaml" +- "!include public_v_user_voice_activity.yaml" - "!include public_v_user_welcomeMsgs.yaml" diff --git a/bbb-graphql-server/metadata/databases/databases.yaml b/bbb-graphql-server/metadata/databases/databases.yaml index cc922cb885..281de7b878 100644 --- a/bbb-graphql-server/metadata/databases/databases.yaml +++ b/bbb-graphql-server/metadata/databases/databases.yaml @@ -16,13 +16,10 @@ kind: postgres configuration: connection_info: - database_url: - connection_parameters: - database: bbb_graphql - host: 127.0.0.1 - password: bbb_graphql - port: 5432 - username: postgres + database_url: postgres://postgres:bbb_graphql@127.0.0.1:5432/bbb_graphql isolation_level: read-committed - use_prepared_statements: false + pool_settings: + connection_lifetime: 3600 + max_connections: 100 + use_prepared_statements: true tables: "!include BigBlueButton/tables/tables.yaml" diff --git a/bbb-graphql-server/metadata/query_collections.yaml b/bbb-graphql-server/metadata/query_collections.yaml index cfbe507e36..ae5fd34da1 100644 --- a/bbb-graphql-server/metadata/query_collections.yaml +++ b/bbb-graphql-server/metadata/query_collections.yaml @@ -1,37 +1,6 @@ - name: allowed-queries definition: queries: - - name: UserCurrent - query: | - query UserCurrent { - user_current { - userId - name - guestStatus - guestStatusDetails { - guestLobbyMessage - positionInWaitingQueue - } - meeting { - name - logoutUrl - } - } - } - - name: clientStartupSettings - query: | - query clientStartupSettings { - meeting_clientSettings { - askForFeedbackOnLogout: clientSettingsJson(path: "$.public.app.askForFeedbackOnLogout") - mediaTag: clientSettingsJson(path: "$.public.media.mediaTag") - allowDefaultLogoutUrl: clientSettingsJson(path: "$.public.app.allowDefaultLogoutUrl") - learningDashboardBase: clientSettingsJson(path: "$.public.app.learningDashboardBase") - fallbackLocale: clientSettingsJson(path: "$.public.app.defaultSettings.application.fallbackLocale") - overrideLocale: clientSettingsJson(path: "$.public.app.defaultSettings.application.overrideLocale") - fallbackOnEmptyString: clientSettingsJson(path: "$.public.app.fallbackOnEmptyLocaleString") - clientLog: clientSettingsJson(path: "$.public.clientLog") - } - } - name: clientSettings query: | query clientStartupSettings { diff --git a/bbb-graphql-server/metadata/rest_endpoints.yaml b/bbb-graphql-server/metadata/rest_endpoints.yaml index 8cc0bf46cc..77cceee094 100644 --- a/bbb-graphql-server/metadata/rest_endpoints.yaml +++ b/bbb-graphql-server/metadata/rest_endpoints.yaml @@ -7,21 +7,3 @@ - GET name: clientSettings url: clientSettings -- comment: "" - definition: - query: - collection_name: allowed-queries - query_name: clientStartupSettings - methods: - - GET - name: clientStartupSettings - url: clientStartupSettings -- comment: "" - definition: - query: - collection_name: allowed-queries - query_name: UserCurrent - methods: - - GET - name: UserCurrent - url: usercurrent diff --git a/bbb-graphql-server/update_graphql_data.sh b/bbb-graphql-server/update_graphql_data.sh deleted file mode 100755 index 53c436ffe6..0000000000 --- a/bbb-graphql-server/update_graphql_data.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -if [ "$EUID" -ne 0 ]; then - echo "Please run this script as root ( or with sudo )" ; - exit 1; -fi; - -cd "$(dirname "$0")" - -export LANGUAGE="en_US.UTF-8" -export LC_ALL="en_US.UTF-8" - -akka_apps_status=$(systemctl is-active "bbb-apps-akka") -hasura_status=$(systemctl is-active "bbb-graphql-server") - -if [ "$akka_apps_status" = "active" ]; then - echo "Stopping Akka-apps" - sudo systemctl stop bbb-apps-akka -fi -if [ "$hasura_status" = "active" ]; then - echo "Stopping Hasura" - sudo systemctl stop bbb-graphql-server -fi - -echo "Restarting database bbb_graphql" -runuser -u postgres -- psql -q -c "drop database if exists bbb_graphql with (force)" -runuser -u postgres -- psql -q -c "create database bbb_graphql WITH TEMPLATE template0 LC_COLLATE 'C.UTF-8'" -runuser -u postgres -- psql -q -c "alter database bbb_graphql set timezone to 'UTC'" - -echo "Creating tables in bbb_graphql" -runuser -u postgres -- psql -U postgres -d bbb_graphql -q -f bbb_schema.sql --set ON_ERROR_STOP=on - -echo "Creating frontend in bbb_graphql" -DATABASE_FRONTEND_USER="bbb_frontend" -FRONT_USER_EXISTS=$(sudo -u postgres psql -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname = '$DATABASE_FRONTEND_USER'") -if [ "$FRONT_USER_EXISTS" = '1' ] -then - echo "User $DATABASE_FRONTEND_USER already exists" -else - sudo -u postgres psql -q -c "CREATE USER $DATABASE_FRONTEND_USER WITH PASSWORD '$DATABASE_FRONTEND_USER'" - sudo -u postgres psql -q -c "GRANT CONNECT ON DATABASE bbb_graphql TO $DATABASE_FRONTEND_USER" - sudo -u postgres psql -q -d bbb_graphql -c "REVOKE ALL ON ALL TABLES IN SCHEMA public FROM $DATABASE_FRONTEND_USER" - sudo -u postgres psql -q -d bbb_graphql -c "GRANT USAGE ON SCHEMA public TO $DATABASE_FRONTEND_USER" - echo "User $DATABASE_FRONTEND_USER created on database bbb_graphql" -fi - -sudo -u postgres psql -q -d bbb_graphql -c "GRANT SELECT ON v_user_connection_auth TO $DATABASE_FRONTEND_USER" - -echo "Starting Hasura" -sudo systemctl start bbb-graphql-server - -#Check if Hasura is ready before applying metadata -HASURA_PORT=8085 -while ! netstat -tuln | grep ":$HASURA_PORT " > /dev/null; do - echo "Waiting for Hasura's port ($HASURA_PORT) to be ready..." - sleep 1 -done - -if [ "$akka_apps_status" = "active" ]; then - echo "Starting Akka-apps" - sudo systemctl start bbb-apps-akka -fi - -echo "Applying new metadata to Hasura" -timeout 15s hasura metadata apply --skip-update-check diff --git a/bbb-learning-dashboard/.eslintrc.js b/bbb-learning-dashboard/.eslintrc.js index db36352796..c06c3f8d99 100644 --- a/bbb-learning-dashboard/.eslintrc.js +++ b/bbb-learning-dashboard/.eslintrc.js @@ -21,6 +21,8 @@ module.exports = { 'import/no-absolute-path': 0, 'import/no-unresolved': 0, 'import/no-extraneous-dependencies': 1, + 'import/no-named-as-default': 0, + 'import/no-named-as-default-member': 0, 'react/prop-types': 'off', 'jsx-a11y/no-access-key': 0, 'react/jsx-props-no-spreading': 'off', diff --git a/bbb-learning-dashboard/package-lock.json b/bbb-learning-dashboard/package-lock.json index a62035be84..9ee5d6fc2c 100644 --- a/bbb-learning-dashboard/package-lock.json +++ b/bbb-learning-dashboard/package-lock.json @@ -1,7 +1,7 @@ { "name": "learning-analytics-dashboard", "version": "0.1.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -27,27 +27,42 @@ "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-react": "^7.24.0", "eslint-plugin-react-hooks": "^4.2.0", - "postcss": "^8.4.36", + "postcss": "^8.4.41", "tailwindcss": "^3.0.11" } }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "license": "Apache-2.0", "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" }, "engines": { @@ -55,31 +70,35 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.17.10", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.18.2", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-compilation-targets": "^7.18.2", - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.0", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2", - "convert-source-map": "^1.7.0", + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -90,27 +109,30 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.18.2", + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.1.tgz", + "integrity": "sha512-Y956ghgTT4j7rKesabkh5WeqgSFZVFwaPR0IWFm7KFHFmmJ4afbG49SmfW4S+GyRPx0Dy5jxEWA5t0rpxfElWg==", "license": "MIT", "dependencies": { - "eslint-scope": "^5.1.1", + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": "^10.13.0 || ^12.13.0 || >=14.0.0" }, "peerDependencies": { - "@babel/core": ">=7.11.0", - "eslint": "^7.5.0 || ^8.0.0" + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/@babel/generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", - "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.0", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -119,67 +141,60 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", "license": "MIT", "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.18.2", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.20.2", - "semver": "^6.3.0" + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.18.0", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz", + "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-member-expression-to-functions": "^7.17.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.4", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -189,11 +204,14 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.17.12", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", + "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "regexpu-core": "^5.0.1" + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -203,228 +221,207 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.1", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" + "resolve": "^1.14.2" }, "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.16.7", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.17.7", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.17.0" + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.18.0", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.17.12", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.16.8", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-wrap-function": "^7.16.8", - "@babel/types": "^7.16.8" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.18.2", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-member-expression-to-functions": "^7.17.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2" + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.18.2", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.18.2" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", "license": "MIT", "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.16.7", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.16.8", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.8", - "@babel/types": "^7.16.8" + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.18.2", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "license": "MIT", "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -434,9 +431,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -444,11 +445,44 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.17.12", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", + "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -458,12 +492,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -472,27 +508,31 @@ "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.17.12", + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-remap-async-to-generator": "^7.16.8", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.17.12", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -501,87 +541,15 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.18.0", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.18.2", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz", + "integrity": "sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-replace-supers": "^7.18.2", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/plugin-syntax-decorators": "^7.17.12", - "charcodes": "^0.2.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.16.7", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.17.12", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.17.12", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.17.12", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-decorators": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -591,10 +559,13 @@ } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.17.12", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -605,10 +576,13 @@ } }, "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.16.7", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -618,43 +592,15 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.0", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-compilation-targets": "^7.17.10", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.17.12" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.7", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.17.12", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -665,11 +611,14 @@ } }, "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.17.12", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -679,14 +628,10 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.17.12", + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-create-class-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, "engines": { "node": ">=6.9.0" }, @@ -694,22 +639,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.17.12", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -720,6 +653,8 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -730,6 +665,8 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" @@ -740,6 +677,8 @@ }, "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -752,10 +691,12 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.7.tgz", + "integrity": "sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -766,6 +707,8 @@ }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -776,6 +719,8 @@ }, "node_modules/@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" @@ -785,10 +730,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz", + "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -798,10 +745,27 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.17.12", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", + "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -812,6 +776,8 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -822,6 +788,8 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -831,10 +799,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -845,6 +815,8 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -855,6 +827,8 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -865,6 +839,8 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" @@ -875,6 +851,8 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -885,6 +863,8 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -895,6 +875,8 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -905,6 +887,8 @@ }, "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -918,6 +902,8 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" @@ -930,10 +916,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.17.12", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -942,11 +930,47 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.17.12", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz", + "integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.4" }, "engines": { "node": ">=6.9.0" @@ -956,12 +980,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-remap-async-to-generator": "^7.16.8" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -971,10 +997,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -984,10 +1012,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.18.4", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -996,17 +1026,50 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.18.4", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz", + "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-replace-supers": "^7.18.2", - "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz", + "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.4", "globals": "^11.1.0" }, "engines": { @@ -1017,10 +1080,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1030,10 +1096,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.18.0", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1043,11 +1111,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1057,10 +1127,44 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1070,11 +1174,29 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1084,11 +1206,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.17.12", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.25.2.tgz", + "integrity": "sha512-InBZ0O8tew5V0K6cHcQ+wgxlrjOw1W4wDXLkOTjLRD8GYhTSkxTVBtdy3MMtvYBrbAWa1Qm3hNoTc1620Yj+Mg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-flow": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-flow": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1098,10 +1222,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.1", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1111,12 +1238,30 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.16.7", + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1126,10 +1271,28 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.17.12", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", + "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { "node": ">=6.9.0" @@ -1139,10 +1302,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1152,12 +1317,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.18.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1167,13 +1333,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.18.2", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-simple-access": "^7.18.2", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1183,14 +1350,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.18.4", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-validator-identifier": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -1200,11 +1368,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1214,11 +1384,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1228,10 +1400,62 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1241,11 +1465,46 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -1255,10 +1514,46 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz", + "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.4", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -1268,10 +1563,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1281,10 +1578,12 @@ } }, "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.17.12", + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.1.tgz", + "integrity": "sha512-SLV/giH/V4SmloZ6Dt40HjTGTAIkxn33TVIHxNGNvo8ezMhrxBkzisj4op1KZYPIOHFLqhv60OHvX+YRu4xbmQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1294,10 +1593,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", + "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1307,14 +1608,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.17.12", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz", + "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-jsx": "^7.17.12", - "@babel/types": "^7.17.12" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/types": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -1324,10 +1627,12 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", + "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", "license": "MIT", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.16.7" + "@babel/plugin-transform-react-jsx": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1337,11 +1642,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", + "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1351,11 +1658,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.18.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" }, "engines": { "node": ">=6.9.0" @@ -1365,10 +1674,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1378,15 +1689,17 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.18.2", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.4.tgz", + "integrity": "sha512-8hsyG+KUYGY0coX6KUCDancA0Vw225KJ2HJO0yCNr1vq5r+lJTleDaJf0K7iOhjw4SWhu03TMBzYTJ9krmzULQ==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.5.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "semver": "^6.3.0" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1396,10 +1709,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1409,11 +1724,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1423,10 +1740,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1436,10 +1755,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.2", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1449,10 +1770,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.17.12", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1462,12 +1785,16 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.18.4", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", + "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-typescript": "^7.17.12" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1477,10 +1804,28 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1490,11 +1835,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.16.7", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1503,37 +1850,46 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env": { - "version": "7.18.2", + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz", + "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-compilation-targets": "^7.18.2", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.17.12", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.17.12", - "@babel/plugin-proposal-async-generator-functions": "^7.17.12", - "@babel/plugin-proposal-class-properties": "^7.17.12", - "@babel/plugin-proposal-class-static-block": "^7.18.0", - "@babel/plugin-proposal-dynamic-import": "^7.16.7", - "@babel/plugin-proposal-export-namespace-from": "^7.17.12", - "@babel/plugin-proposal-json-strings": "^7.17.12", - "@babel/plugin-proposal-logical-assignment-operators": "^7.17.12", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.17.12", - "@babel/plugin-proposal-numeric-separator": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.18.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", - "@babel/plugin-proposal-optional-chaining": "^7.17.12", - "@babel/plugin-proposal-private-methods": "^7.17.12", - "@babel/plugin-proposal-private-property-in-object": "^7.17.12", - "@babel/plugin-proposal-unicode-property-regex": "^7.17.12", + "@babel/helper-create-regexp-features-plugin": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz", + "integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.4", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.17.12", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1543,45 +1899,62 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.17.12", - "@babel/plugin-transform-async-to-generator": "^7.17.12", - "@babel/plugin-transform-block-scoped-functions": "^7.16.7", - "@babel/plugin-transform-block-scoping": "^7.17.12", - "@babel/plugin-transform-classes": "^7.17.12", - "@babel/plugin-transform-computed-properties": "^7.17.12", - "@babel/plugin-transform-destructuring": "^7.18.0", - "@babel/plugin-transform-dotall-regex": "^7.16.7", - "@babel/plugin-transform-duplicate-keys": "^7.17.12", - "@babel/plugin-transform-exponentiation-operator": "^7.16.7", - "@babel/plugin-transform-for-of": "^7.18.1", - "@babel/plugin-transform-function-name": "^7.16.7", - "@babel/plugin-transform-literals": "^7.17.12", - "@babel/plugin-transform-member-expression-literals": "^7.16.7", - "@babel/plugin-transform-modules-amd": "^7.18.0", - "@babel/plugin-transform-modules-commonjs": "^7.18.2", - "@babel/plugin-transform-modules-systemjs": "^7.18.0", - "@babel/plugin-transform-modules-umd": "^7.18.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.17.12", - "@babel/plugin-transform-new-target": "^7.17.12", - "@babel/plugin-transform-object-super": "^7.16.7", - "@babel/plugin-transform-parameters": "^7.17.12", - "@babel/plugin-transform-property-literals": "^7.16.7", - "@babel/plugin-transform-regenerator": "^7.18.0", - "@babel/plugin-transform-reserved-words": "^7.17.12", - "@babel/plugin-transform-shorthand-properties": "^7.16.7", - "@babel/plugin-transform-spread": "^7.17.12", - "@babel/plugin-transform-sticky-regex": "^7.16.7", - "@babel/plugin-transform-template-literals": "^7.18.2", - "@babel/plugin-transform-typeof-symbol": "^7.17.12", - "@babel/plugin-transform-unicode-escapes": "^7.16.7", - "@babel/plugin-transform-unicode-regex": "^7.16.7", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.18.2", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.5.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.22.1", - "semver": "^6.3.0" + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.25.4", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.4", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.37.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1591,29 +1964,31 @@ } }, "node_modules/@babel/preset-modules": { - "version": "0.1.5", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/preset-react": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", + "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-react-display-name": "^7.16.7", - "@babel/plugin-transform-react-jsx": "^7.17.12", - "@babel/plugin-transform-react-jsx-development": "^7.16.7", - "@babel/plugin-transform-react-pure-annotations": "^7.16.7" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.24.7", + "@babel/plugin-transform-react-jsx-development": "^7.24.7", + "@babel/plugin-transform-react-pure-annotations": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1623,12 +1998,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.17.12", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-typescript": "^7.17.12" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1637,53 +2016,49 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.20.1", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.13.10" - }, - "engines": { - "node": ">=6.9.0" - } + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "license": "MIT" }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.18.3", + "node_modules/@babel/runtime": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "license": "MIT", "dependencies": { - "core-js-pure": "^3.20.2", - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1692,12 +2067,13 @@ } }, "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1706,17 +2082,23 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "license": "MIT" }, "node_modules/@csstools/normalize.css": { - "version": "12.0.0", + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", + "integrity": "sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ==", "license": "CC0-1.0" }, "node_modules/@csstools/postcss-cascade-layers": { - "version": "1.0.3", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", "license": "CC0-1.0", "dependencies": { - "@csstools/selector-specificity": "^2.0.0", + "@csstools/selector-specificity": "^2.0.2", "postcss-selector-parser": "^6.0.10" }, "engines": { @@ -1727,11 +2109,13 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2" } }, "node_modules/@csstools/postcss-color-function": { - "version": "1.1.0", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", @@ -1745,24 +2129,13 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, "node_modules/@csstools/postcss-font-format-keywords": { - "version": "1.0.0", - "license": "CC0-1.0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/@csstools/postcss-hwb-function": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -1775,11 +2148,32 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/@csstools/postcss-ic-unit": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", @@ -1788,12 +2182,18 @@ "engines": { "node": "^12 || ^14 || >=16" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2" } }, "node_modules/@csstools/postcss-is-pseudo-class": { - "version": "2.0.5", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", @@ -1807,11 +2207,13 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, - "node_modules/@csstools/postcss-normalize-display-values": { + "node_modules/@csstools/postcss-nested-calc": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -1819,12 +2221,37 @@ "engines": { "node": "^12 || ^14 || >=16" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/@csstools/postcss-oklab-function": { - "version": "1.1.0", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", @@ -1838,11 +2265,13 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, "node_modules/@csstools/postcss-progressive-custom-properties": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -1855,7 +2284,9 @@ } }, "node_modules/@csstools/postcss-stepped-value-functions": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -1868,11 +2299,32 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/@csstools/postcss-trigonometric-functions": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -1885,11 +2337,13 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, "node_modules/@csstools/postcss-unset-value": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" @@ -1899,175 +2353,217 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2" } }, "node_modules/@csstools/selector-specificity": { - "version": "2.0.0", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", "license": "CC0-1.0", "engines": { - "node": "^12 || ^14 || >=16" + "node": "^14 || ^16 || >=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.3", "postcss-selector-parser": "^6.0.10" } }, "node_modules/@emotion/babel-plugin": { - "version": "11.10.5", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.1", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.1.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "stylis": "4.2.0" } }, - "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/source-map": { - "version": "0.5.7", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" }, "node_modules/@emotion/cache": { - "version": "11.10.5", + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", "license": "MIT", "dependencies": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.1", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.1.3" + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" } }, "node_modules/@emotion/hash": { - "version": "0.9.0", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", "license": "MIT" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.2.0", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", + "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", "license": "MIT", "dependencies": { - "@emotion/memoize": "^0.8.0" + "@emotion/memoize": "^0.9.0" } }, "node_modules/@emotion/memoize": { - "version": "0.8.0", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", "license": "MIT" }, "node_modules/@emotion/react": { - "version": "11.10.5", + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", - "@emotion/cache": "^11.10.5", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0", "react": ">=16.8.0" }, "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, "@types/react": { "optional": true } } }, "node_modules/@emotion/serialize": { - "version": "1.1.1", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.1.tgz", + "integrity": "sha512-dEPNKzBPU+vFPGa+z3axPRn8XVDetYORmDC0wAiej+TNcOZE70ZMJa0X7JdeoM6q/nWTMZeLpN/fTnD9o8MQBA==", "license": "MIT", "dependencies": { - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/unitless": "^0.8.0", - "@emotion/utils": "^1.2.0", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.0", "csstype": "^3.0.2" } }, "node_modules/@emotion/sheet": { - "version": "1.2.1", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", "license": "MIT" }, "node_modules/@emotion/styled": { - "version": "11.10.5", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", - "@emotion/is-prop-valid": "^1.2.0", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0" + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" }, "peerDependencies": { - "@babel/core": "^7.0.0", "@emotion/react": "^11.0.0-rc.0", "react": ">=16.8.0" }, "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, "@types/react": { "optional": true } } }, "node_modules/@emotion/unitless": { - "version": "0.8.0", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", "license": "MIT" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.0", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", "license": "MIT", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { - "version": "1.2.0", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==", "license": "MIT" }, "node_modules/@emotion/weak-memoize": { - "version": "0.3.0", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", "license": "MIT" }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -2085,7 +2581,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.15.0", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -2099,6 +2597,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -2107,8 +2607,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@formatjs/ecma402-abstract": { "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz", + "integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==", "license": "MIT", "dependencies": { "@formatjs/intl-localematcher": "0.2.25", @@ -2117,6 +2628,8 @@ }, "node_modules/@formatjs/fast-memoize": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz", + "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==", "license": "MIT", "dependencies": { "tslib": "^2.1.0" @@ -2124,6 +2637,8 @@ }, "node_modules/@formatjs/icu-messageformat-parser": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz", + "integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==", "license": "MIT", "dependencies": { "@formatjs/ecma402-abstract": "1.11.4", @@ -2133,6 +2648,8 @@ }, "node_modules/@formatjs/icu-skeleton-parser": { "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz", + "integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==", "license": "MIT", "dependencies": { "@formatjs/ecma402-abstract": "1.11.4", @@ -2141,6 +2658,8 @@ }, "node_modules/@formatjs/intl": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.2.1.tgz", + "integrity": "sha512-vgvyUOOrzqVaOFYzTf2d3+ToSkH2JpR7x/4U1RyoHQLmvEaTQvXJ7A2qm1Iy3brGNXC/+/7bUlc3lpH+h/LOJA==", "license": "MIT", "dependencies": { "@formatjs/ecma402-abstract": "1.11.4", @@ -2162,6 +2681,8 @@ }, "node_modules/@formatjs/intl-displaynames": { "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-5.4.3.tgz", + "integrity": "sha512-4r12A3mS5dp5hnSaQCWBuBNfi9Amgx2dzhU4lTFfhSxgb5DOAiAbMpg6+7gpWZgl4ahsj3l2r/iHIjdmdXOE2Q==", "license": "MIT", "dependencies": { "@formatjs/ecma402-abstract": "1.11.4", @@ -2171,6 +2692,8 @@ }, "node_modules/@formatjs/intl-listformat": { "version": "6.5.3", + "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.5.3.tgz", + "integrity": "sha512-ozpz515F/+3CU+HnLi5DYPsLa6JoCfBggBSSg/8nOB5LYSFW9+ZgNQJxJ8tdhKYeODT+4qVHX27EeJLoxLGLNg==", "license": "MIT", "dependencies": { "@formatjs/ecma402-abstract": "1.11.4", @@ -2180,6 +2703,8 @@ }, "node_modules/@formatjs/intl-localematcher": { "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz", + "integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==", "license": "MIT", "dependencies": { "tslib": "^2.1.0" @@ -2187,6 +2712,9 @@ }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "deprecated": "Use @eslint/config-array instead", "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", @@ -2197,12 +2725,120 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "deprecated": "Use @eslint/object-schema instead", "license": "BSD-3-Clause" }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "license": "ISC", "dependencies": { "camelcase": "^5.3.1", @@ -2217,71 +2853,17 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { - "version": "2.2.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "license": "MIT", "engines": { "node": ">=8" @@ -2289,6 +2871,8 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "license": "MIT", "engines": { "node": ">=8" @@ -2296,6 +2880,8 @@ }, "node_modules/@jest/console": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -2311,6 +2897,8 @@ }, "node_modules/@jest/console/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2324,6 +2912,8 @@ }, "node_modules/@jest/console/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -2338,6 +2928,8 @@ }, "node_modules/@jest/console/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2348,10 +2940,14 @@ }, "node_modules/@jest/console/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/@jest/console/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -2359,6 +2955,8 @@ }, "node_modules/@jest/console/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -2369,6 +2967,8 @@ }, "node_modules/@jest/core": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", "license": "MIT", "dependencies": { "@jest/console": "^27.5.1", @@ -2414,6 +3014,8 @@ }, "node_modules/@jest/core/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2427,6 +3029,8 @@ }, "node_modules/@jest/core/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -2441,6 +3045,8 @@ }, "node_modules/@jest/core/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2451,10 +3057,14 @@ }, "node_modules/@jest/core/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/@jest/core/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -2462,6 +3072,8 @@ }, "node_modules/@jest/core/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -2472,6 +3084,8 @@ }, "node_modules/@jest/environment": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", "license": "MIT", "dependencies": { "@jest/fake-timers": "^27.5.1", @@ -2485,6 +3099,8 @@ }, "node_modules/@jest/fake-timers": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -2500,6 +3116,8 @@ }, "node_modules/@jest/globals": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", @@ -2512,6 +3130,8 @@ }, "node_modules/@jest/reporters": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", @@ -2554,6 +3174,8 @@ }, "node_modules/@jest/reporters/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2567,6 +3189,8 @@ }, "node_modules/@jest/reporters/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -2581,6 +3205,8 @@ }, "node_modules/@jest/reporters/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2591,17 +3217,32 @@ }, "node_modules/@jest/reporters/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/@jest/reporters/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@jest/reporters/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -2611,10 +3252,12 @@ } }, "node_modules/@jest/schemas": { - "version": "28.0.2", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.23.3" + "@sinclair/typebox": "^0.24.1" }, "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" @@ -2622,6 +3265,8 @@ }, "node_modules/@jest/source-map": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", "license": "MIT", "dependencies": { "callsites": "^3.0.0", @@ -2632,8 +3277,19 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@jest/test-result": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", "license": "MIT", "dependencies": { "@jest/console": "^27.5.1", @@ -2647,6 +3303,8 @@ }, "node_modules/@jest/test-sequencer": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", "license": "MIT", "dependencies": { "@jest/test-result": "^27.5.1", @@ -2660,6 +3318,8 @@ }, "node_modules/@jest/transform": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "license": "MIT", "dependencies": { "@babel/core": "^7.1.0", @@ -2684,6 +3344,8 @@ }, "node_modules/@jest/transform/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2697,6 +3359,8 @@ }, "node_modules/@jest/transform/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -2711,6 +3375,8 @@ }, "node_modules/@jest/transform/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2721,17 +3387,38 @@ }, "node_modules/@jest/transform/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "license": "MIT" }, "node_modules/@jest/transform/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@jest/transform/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -2742,6 +3429,8 @@ }, "node_modules/@jest/types": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -2756,6 +3445,8 @@ }, "node_modules/@jest/types/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2769,6 +3460,8 @@ }, "node_modules/@jest/types/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -2783,6 +3476,8 @@ }, "node_modules/@jest/types/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2793,10 +3488,14 @@ }, "node_modules/@jest/types/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/@jest/types/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -2804,6 +3503,8 @@ }, "node_modules/@jest/types/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -2813,20 +3514,24 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -2835,108 +3540,70 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "license": "MIT" - }, - "node_modules/@mui/base": { - "version": "5.0.0-alpha.105", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.19.0", - "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", - "@popperjs/core": "^2.11.6", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui" - }, - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/base/node_modules/react-is": { - "version": "18.2.0", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "license": "MIT" }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.10.13", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz", + "integrity": "sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==", "license": "MIT", "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/material": { - "version": "5.10.13", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", + "integrity": "sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.19.0", - "@mui/base": "5.0.0-alpha.105", - "@mui/core-downloads-tracker": "^5.10.13", - "@mui/system": "^5.10.13", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", - "@types/react-transition-group": "^4.4.5", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.7", + "@mui/system": "^5.16.7", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1", - "react-is": "^18.2.0", + "react-is": "^18.3.1", "react-transition-group": "^4.4.5" }, "engines": { @@ -2944,7 +3611,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -2965,16 +3632,14 @@ } } }, - "node_modules/@mui/material/node_modules/react-is": { - "version": "18.2.0", - "license": "MIT" - }, "node_modules/@mui/private-theming": { - "version": "5.10.9", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", + "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.19.0", - "@mui/utils": "^5.10.9", + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.6", "prop-types": "^15.8.1" }, "engines": { @@ -2982,7 +3647,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -2995,12 +3660,14 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.10.8", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", + "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.19.0", - "@emotion/cache": "^11.10.3", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { @@ -3008,7 +3675,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.4.1", @@ -3025,16 +3692,18 @@ } }, "node_modules/@mui/system": { - "version": "5.10.13", + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz", + "integrity": "sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.19.0", - "@mui/private-theming": "^5.10.9", - "@mui/styled-engine": "^5.10.8", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.6", + "@mui/styled-engine": "^5.16.6", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { @@ -3042,7 +3711,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -3063,10 +3732,12 @@ } }, "node_modules/@mui/types": { - "version": "7.2.0", + "version": "7.2.16", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.16.tgz", + "integrity": "sha512-qI8TV3M7ShITEEc8Ih15A2vLzZGLhD+/UPNwck/hcls2gwg7dyRjNGXcQYHKLB5Q7PuTRfrTkAoPa2VV1s67Ag==", "license": "MIT", "peerDependencies": { - "@types/react": "*" + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3075,32 +3746,39 @@ } }, "node_modules/@mui/utils": { - "version": "5.10.9", + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", + "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.19.0", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", + "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "react-is": "^18.3.1" }, "engines": { "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@mui/utils/node_modules/react-is": { - "version": "18.2.0", - "license": "MIT" - }, "node_modules/@mui/x-data-grid": { - "version": "5.17.10", + "version": "5.17.26", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-5.17.26.tgz", + "integrity": "sha512-eGJq9J0g9cDGLFfMmugOadZx0mJeOd/yQpHwEa5gUXyONS6qF0OhXSWyDOhDdA3l2TOoQzotMN5dY/T4Wl1KYA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.9", @@ -3123,8 +3801,28 @@ "react-dom": "^17.0.2 || ^18.0.0" } }, + "node_modules/@mui/x-data-grid/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "license": "MIT", + "dependencies": { + "eslint-scope": "5.1.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -3136,6 +3834,8 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "license": "MIT", "engines": { "node": ">= 8" @@ -3143,6 +3843,8 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -3152,18 +3854,28 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.7", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", + "integrity": "sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==", "license": "MIT", "dependencies": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.8.1", + "ansi-html": "^0.0.9", + "core-js-pure": "^3.23.3", "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", "html-entities": "^2.1.0", - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0", + "loader-utils": "^2.0.4", + "schema-utils": "^4.2.0", "source-map": "^0.7.3" }, "engines": { @@ -3173,9 +3885,9 @@ "@types/webpack": "4.x || 5.x", "react-refresh": ">=0.10.0 <1.0.0", "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <3.0.0", + "type-fest": ">=0.17.0 <5.0.0", "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x", + "webpack-dev-server": "3.x || 4.x || 5.x", "webpack-hot-middleware": "2.x", "webpack-plugin-serve": "0.x || 1.x" }, @@ -3200,75 +3912,19 @@ } } }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/find-up": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/locate-path": { - "version": "6.0.0", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/p-limit": { - "version": "3.1.0", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/p-locate": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/path-exists": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, "node_modules/@popperjs/core": { - "version": "2.11.6", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "license": "MIT", "funding": { "type": "opencollective", @@ -3277,6 +3933,8 @@ }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.10.4", @@ -3298,6 +3956,8 @@ }, "node_modules/@rollup/plugin-node-resolve": { "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.1.0", @@ -3316,6 +3976,8 @@ }, "node_modules/@rollup/plugin-replace": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.1.0", @@ -3327,6 +3989,8 @@ }, "node_modules/@rollup/pluginutils": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", "license": "MIT", "dependencies": { "@types/estree": "0.0.39", @@ -3342,18 +4006,32 @@ }, "node_modules/@rollup/pluginutils/node_modules/@types/estree": { "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "license": "MIT" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "license": "MIT" }, "node_modules/@rushstack/eslint-patch": { - "version": "1.1.3", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", + "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", "license": "MIT" }, "node_modules/@sinclair/typebox": { - "version": "0.23.5", + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", "license": "MIT" }, "node_modules/@sinonjs/commons": { - "version": "1.8.3", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" @@ -3361,6 +4039,8 @@ }, "node_modules/@sinonjs/fake-timers": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^1.7.0" @@ -3368,6 +4048,8 @@ }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", "license": "Apache-2.0", "dependencies": { "ejs": "^3.1.6", @@ -3378,6 +4060,8 @@ }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", "license": "MIT", "engines": { "node": ">=10" @@ -3389,6 +4073,8 @@ }, "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", "license": "MIT", "engines": { "node": ">=10" @@ -3400,6 +4086,8 @@ }, "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", "license": "MIT", "engines": { "node": ">=10" @@ -3411,6 +4099,8 @@ }, "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", "license": "MIT", "engines": { "node": ">=10" @@ -3422,6 +4112,8 @@ }, "node_modules/@svgr/babel-plugin-svg-dynamic-title": { "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", "license": "MIT", "engines": { "node": ">=10" @@ -3433,6 +4125,8 @@ }, "node_modules/@svgr/babel-plugin-svg-em-dimensions": { "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", "license": "MIT", "engines": { "node": ">=10" @@ -3444,6 +4138,8 @@ }, "node_modules/@svgr/babel-plugin-transform-react-native-svg": { "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", "license": "MIT", "engines": { "node": ">=10" @@ -3455,6 +4151,8 @@ }, "node_modules/@svgr/babel-plugin-transform-svg-component": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", "license": "MIT", "engines": { "node": ">=10" @@ -3466,6 +4164,8 @@ }, "node_modules/@svgr/babel-preset": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", "license": "MIT", "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", @@ -3487,6 +4187,8 @@ }, "node_modules/@svgr/core": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", "license": "MIT", "dependencies": { "@svgr/plugin-jsx": "^5.5.0", @@ -3503,6 +4205,8 @@ }, "node_modules/@svgr/hast-util-to-babel-ast": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", "license": "MIT", "dependencies": { "@babel/types": "^7.12.6" @@ -3517,6 +4221,8 @@ }, "node_modules/@svgr/plugin-jsx": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", "license": "MIT", "dependencies": { "@babel/core": "^7.12.3", @@ -3534,6 +4240,8 @@ }, "node_modules/@svgr/plugin-svgo": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", "license": "MIT", "dependencies": { "cosmiconfig": "^7.0.0", @@ -3550,6 +4258,8 @@ }, "node_modules/@svgr/webpack": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", "license": "MIT", "dependencies": { "@babel/core": "^7.12.3", @@ -3571,6 +4281,8 @@ }, "node_modules/@tootallnate/once": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "license": "MIT", "engines": { "node": ">= 6" @@ -3578,31 +4290,39 @@ }, "node_modules/@trysound/sax": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "license": "ISC", "engines": { "node": ">=10.13.0" } }, "node_modules/@types/babel__core": { - "version": "7.1.19", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "node_modules/@types/babel__generator": { - "version": "7.6.4", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.1", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", @@ -3610,14 +4330,18 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.17.1", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { - "version": "1.19.2", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "license": "MIT", "dependencies": { "@types/connect": "*", @@ -3625,21 +4349,27 @@ } }, "node_modules/@types/bonjour": { - "version": "3.5.10", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect": { - "version": "3.4.35", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.3.5", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "license": "MIT", "dependencies": { "@types/express-serve-static-core": "*", @@ -3647,54 +4377,58 @@ } }, "node_modules/@types/eslint": { - "version": "7.29.0", + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.3", - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "license": "MIT" }, "node_modules/@types/express": { - "version": "4.17.13", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "license": "MIT", "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.28", + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "node_modules/@types/graceful-fs": { - "version": "4.1.5", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.1", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", "license": "MIT", "dependencies": { "@types/react": "*", @@ -3703,91 +4437,135 @@ }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "license": "MIT" }, "node_modules/@types/http-proxy": { - "version": "1.17.9", + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.1", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/json-schema": { - "version": "7.0.11", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "license": "MIT" }, "node_modules/@types/mime": { - "version": "1.3.2", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "license": "MIT" }, "node_modules/@types/node": { - "version": "17.0.41", - "license": "MIT" + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/parse-json": { - "version": "4.0.0", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "license": "MIT" }, "node_modules/@types/prettier": { - "version": "2.6.3", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.5", + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", "license": "MIT" }, "node_modules/@types/q": { - "version": "1.5.5", + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", + "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==", "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.7", + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", "license": "MIT" }, "node_modules/@types/range-parser": { - "version": "1.2.4", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "license": "MIT" }, "node_modules/@types/react": { - "version": "18.0.12", + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", + "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", "license": "MIT", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, - "node_modules/@types/react-is": { - "version": "17.0.3", - "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-transition-group": { - "version": "4.4.5", + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", + "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", "license": "MIT", "dependencies": { "@types/react": "*" @@ -3795,6 +4573,8 @@ }, "node_modules/@types/resolve": { "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -3802,71 +4582,105 @@ }, "node_modules/@types/retry": { "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "license": "MIT" }, - "node_modules/@types/scheduler": { - "version": "0.16.2", + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "license": "MIT" }, - "node_modules/@types/serve-index": { - "version": "1.9.1", - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.13.10", + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/@types/sockjs": { - "version": "0.3.33", + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/stack-utils": { - "version": "2.0.1", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "license": "MIT" }, "node_modules/@types/trusted-types": { - "version": "2.0.2", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.3", + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/yargs": { - "version": "16.0.4", + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.0", + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.27.1", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/type-utils": "5.27.1", - "@typescript-eslint/utils": "5.27.1", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "regexpp": "^3.2.0", + "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", "tsutils": "^3.21.0" }, @@ -3888,19 +4702,19 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "5.2.0", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3909,10 +4723,12 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.27.1", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "5.27.1" + "@typescript-eslint/utils": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3926,12 +4742,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.27.1", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/typescript-estree": "5.27.1", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "engines": { @@ -3951,11 +4769,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.27.1", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/visitor-keys": "5.27.1" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3966,10 +4786,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.27.1", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "5.27.1", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -3990,7 +4813,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.27.1", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4001,11 +4826,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.27.1", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/visitor-keys": "5.27.1", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4026,12 +4853,10 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4040,15 +4865,19 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.27.1", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "license": "MIT", "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/typescript-estree": "5.27.1", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "semver": "^7.3.7" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4061,27 +4890,25 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-utils": { - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "node": ">=10" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.27.1", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -4093,16 +4920,28 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.3.0", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "license": "ISC" + }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -4111,22 +4950,26 @@ "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -4136,12 +4979,14 @@ "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -4153,6 +4998,7 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -4161,6 +5007,7 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } @@ -4168,12 +5015,14 @@ "node_modules/@webassemblyjs/utf8": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -4189,6 +5038,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -4201,6 +5051,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -4212,6 +5063,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", @@ -4225,6 +5077,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" @@ -4233,19 +5086,26 @@ "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" }, "node_modules/abab": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", "license": "BSD-3-Clause" }, "node_modules/accepts": { "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "license": "MIT", "dependencies": { "mime-types": "~2.1.34", @@ -4257,6 +5117,8 @@ }, "node_modules/acorn": { "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -4267,6 +5129,8 @@ }, "node_modules/acorn-globals": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "license": "MIT", "dependencies": { "acorn": "^7.1.1", @@ -4275,29 +5139,26 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-node": { - "version": "1.8.2", - "license": "Apache-2.0", - "dependencies": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - } - }, "node_modules/acorn-walk": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/address": { - "version": "1.2.0", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -4305,6 +5166,8 @@ }, "node_modules/adjust-sourcemap-loader": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", @@ -4316,6 +5179,8 @@ }, "node_modules/agent-base": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "license": "MIT", "dependencies": { "debug": "4" @@ -4326,6 +5191,8 @@ }, "node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -4340,6 +5207,8 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -4354,13 +5223,15 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.0", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -4369,10 +5240,14 @@ }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/ajv-keywords": { "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" @@ -4380,6 +5255,8 @@ }, "node_modules/ansi-colors": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "license": "MIT", "engines": { "node": ">=6" @@ -4387,6 +5264,8 @@ }, "node_modules/ansi-escapes": { "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -4398,8 +5277,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-html": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.9.tgz", + "integrity": "sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg==", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "engines": [ "node >= 0.8.0" ], @@ -4410,6 +5303,8 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" @@ -4417,6 +5312,8 @@ }, "node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "license": "MIT", "dependencies": { "color-convert": "^1.9.0" @@ -4425,8 +5322,16 @@ "node": ">=4" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, "node_modules/anymatch": { - "version": "3.1.2", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -4438,27 +5343,61 @@ }, "node_modules/arg": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", "license": "MIT" }, "node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, + "node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-flatten": { - "version": "2.1.2", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, "node_modules/array-includes": { - "version": "3.1.5", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -4470,18 +5409,62 @@ }, "node_modules/array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { - "version": "1.3.0", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -4492,12 +5475,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.0", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -4508,13 +5493,17 @@ } }, "node_modules/array.prototype.reduce": { - "version": "1.0.4", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.7.tgz", + "integrity": "sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", "es-array-method-boxes-properly": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "is-string": "^1.0.7" }, "engines": { @@ -4524,38 +5513,90 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/asap": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, "node_modules/ast-types-flow": { - "version": "0.0.7", - "license": "ISC" + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "license": "MIT" }, "node_modules/astral-regex": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/async": { - "version": "3.2.4", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/at-least-node": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "license": "ISC", "engines": { "node": ">= 4.0.0" } }, "node_modules/autoprefixer": { - "version": "10.4.7", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "funding": [ { "type": "opencollective", @@ -4564,15 +5605,19 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "license": "MIT", "dependencies": { - "browserslist": "^4.20.3", - "caniuse-lite": "^1.0.30001335", - "fraction.js": "^4.2.0", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -4585,19 +5630,43 @@ "postcss": "^8.1.0" } }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axe-core": { - "version": "4.4.2", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", + "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", "license": "MPL-2.0", "engines": { - "node": ">=12" + "node": ">=4" } }, "node_modules/axobject-query": { - "version": "2.2.0", - "license": "Apache-2.0" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } }, "node_modules/babel-jest": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", "license": "MIT", "dependencies": { "@jest/transform": "^27.5.1", @@ -4618,6 +5687,8 @@ }, "node_modules/babel-jest/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -4631,6 +5702,8 @@ }, "node_modules/babel-jest/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -4645,6 +5718,8 @@ }, "node_modules/babel-jest/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4655,10 +5730,14 @@ }, "node_modules/babel-jest/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/babel-jest/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -4666,6 +5745,8 @@ }, "node_modules/babel-jest/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -4675,7 +5756,9 @@ } }, "node_modules/babel-loader": { - "version": "8.2.5", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", "license": "MIT", "dependencies": { "find-cache-dir": "^3.3.1", @@ -4693,6 +5776,8 @@ }, "node_modules/babel-loader/node_modules/schema-utils": { "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.5", @@ -4707,15 +5792,10 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "license": "MIT", - "dependencies": { - "object.assign": "^4.1.0" - } - }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -4730,6 +5810,8 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", @@ -4743,6 +5825,8 @@ }, "node_modules/babel-plugin-macros": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", @@ -4756,64 +5840,79 @@ }, "node_modules/babel-plugin-named-asset-import": { "version": "0.3.8", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", "license": "MIT", "peerDependencies": { "@babel/core": "^7.1.0" } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.1", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.1", - "semver": "^6.1.1" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.5.2", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.1", - "core-js-compat": "^3.21.0" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.3.1", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", "license": "MIT" }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -4821,6 +5920,8 @@ }, "node_modules/babel-preset-jest": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^27.5.1", @@ -4835,6 +5936,8 @@ }, "node_modules/babel-preset-react-app": { "version": "10.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", + "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", @@ -4857,19 +5960,26 @@ }, "node_modules/balanced-match": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/batch": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "license": "MIT" }, "node_modules/bfj": { - "version": "7.0.2", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", + "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", "license": "MIT", "dependencies": { - "bluebird": "^3.5.5", - "check-types": "^11.1.1", + "bluebird": "^3.7.2", + "check-types": "^11.2.3", "hoopy": "^0.1.4", + "jsonpath": "^1.1.1", "tryer": "^1.0.1" }, "engines": { @@ -4878,26 +5988,36 @@ }, "node_modules/big.js": { "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "license": "MIT", "engines": { "node": "*" } }, "node_modules/binary-extensions": { - "version": "2.2.0", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bluebird": { "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "license": "MIT" }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -4921,6 +6041,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4929,6 +6050,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -4937,6 +6059,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -4947,24 +6070,29 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/bonjour-service": { - "version": "1.0.13", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "license": "MIT", "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "node_modules/boolbase": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "license": "ISC" }, "node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -4972,10 +6100,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -4983,12 +6113,14 @@ }, "node_modules/browser-process-hrtime": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "license": "BSD-2-Clause" }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "funding": [ { "type": "opencollective", @@ -5003,11 +6135,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -5018,6 +6151,8 @@ }, "node_modules/bser": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" @@ -5025,10 +6160,14 @@ }, "node_modules/buffer-from": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "license": "MIT" }, "node_modules/builtin-modules": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "license": "MIT", "engines": { "node": ">=6" @@ -5039,17 +6178,27 @@ }, "node_modules/bytes": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/call-bind": { - "version": "1.0.2", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5057,6 +6206,8 @@ }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "license": "MIT", "engines": { "node": ">=6" @@ -5064,6 +6215,8 @@ }, "node_modules/camel-case": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", @@ -5072,6 +6225,8 @@ }, "node_modules/camelcase": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "license": "MIT", "engines": { "node": ">=10" @@ -5082,6 +6237,8 @@ }, "node_modules/camelcase-css": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", "license": "MIT", "engines": { "node": ">= 6" @@ -5089,6 +6246,8 @@ }, "node_modules/caniuse-api": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "license": "MIT", "dependencies": { "browserslist": "^4.0.0", @@ -5098,9 +6257,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001551", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001551.tgz", - "integrity": "sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==", + "version": "1.0.30001657", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001657.tgz", + "integrity": "sha512-DPbJAlP8/BAXy3IgiWmZKItubb3TYGP0WscQQlVGIfT4s/YlFYVuJgyOsQNP7rJRChx/qdMeLJQJP0Sgg2yjNA==", "funding": [ { "type": "opencollective", @@ -5114,10 +6273,13 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", "license": "MIT", "engines": { "node": ">=4" @@ -5125,6 +6287,8 @@ }, "node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", @@ -5135,32 +6299,34 @@ "node": ">=4" } }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/char-regex": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "license": "MIT", "engines": { "node": ">=10" } }, - "node_modules/charcodes": { - "version": "0.2.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/check-types": { - "version": "11.1.2", + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==", "license": "MIT" }, "node_modules/chokidar": { - "version": "3.5.3", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "license": "MIT", "dependencies": { "anymatch": "~3.1.2", @@ -5174,27 +6340,47 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/chrome-trace-event": { - "version": "1.0.3", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/ci-info": { - "version": "3.3.1", - "license": "MIT" + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.0.tgz", + "integrity": "sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g==", "license": "MIT" }, "node_modules/clean-css": { - "version": "5.3.0", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", "license": "MIT", "dependencies": { "source-map": "~0.6.0" @@ -5203,8 +6389,19 @@ "node": ">= 10.0" } }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -5213,7 +6410,9 @@ } }, "node_modules/clsx": { - "version": "1.2.1", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", "engines": { "node": ">=6" @@ -5221,6 +6420,8 @@ }, "node_modules/co": { "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "license": "MIT", "engines": { "iojs": ">= 1.0.0", @@ -5229,6 +6430,8 @@ }, "node_modules/coa": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", "license": "MIT", "dependencies": { "@types/q": "^1.5.1", @@ -5240,11 +6443,15 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "license": "MIT" }, "node_modules/color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "license": "MIT", "dependencies": { "color-name": "1.1.3" @@ -5252,18 +6459,26 @@ }, "node_modules/color-name": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "license": "MIT" }, "node_modules/colord": { - "version": "2.9.2", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "license": "MIT" }, "node_modules/colorette": { - "version": "2.0.17", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -5274,17 +6489,17 @@ }, "node_modules/commander": { "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "license": "MIT", "engines": { "node": ">= 12" } }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "license": "ISC" - }, "node_modules/common-tags": { "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "license": "MIT", "engines": { "node": ">=4.0.0" @@ -5292,10 +6507,14 @@ }, "node_modules/commondir": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "license": "MIT" }, "node_modules/compressible": { "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" @@ -5306,6 +6525,8 @@ }, "node_modules/compression": { "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "license": "MIT", "dependencies": { "accepts": "~1.3.5", @@ -5322,6 +6543,8 @@ }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -5329,18 +6552,32 @@ }, "node_modules/compression/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, "node_modules/confusing-browser-globals": { "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "license": "MIT" }, "node_modules/connect-history-api-fallback": { - "version": "1.6.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "license": "MIT", "engines": { "node": ">=0.8" @@ -5348,6 +6585,8 @@ }, "node_modules/content-disposition": { "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -5356,53 +6595,40 @@ "node": ">= 0.6" } }, - "node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { - "version": "1.8.0", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.1" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, "node_modules/core-js": { - "version": "3.22.8", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz", + "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -5411,11 +6637,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", - "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "license": "MIT", "dependencies": { - "browserslist": "^4.22.1" + "browserslist": "^4.23.3" }, "funding": { "type": "opencollective", @@ -5423,7 +6650,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.22.8", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.1.tgz", + "integrity": "sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -5433,10 +6662,14 @@ }, "node_modules/core-util-is": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, "node_modules/cosmiconfig": { - "version": "7.0.1", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", @@ -5451,6 +6684,8 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -5463,6 +6698,8 @@ }, "node_modules/crypto-random-string": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "license": "MIT", "engines": { "node": ">=8" @@ -5470,6 +6707,8 @@ }, "node_modules/css-blank-pseudo": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" @@ -5485,7 +6724,9 @@ } }, "node_modules/css-declaration-sorter": { - "version": "6.2.2", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", "license": "ISC", "engines": { "node": "^10 || ^12 || >=14" @@ -5496,6 +6737,8 @@ }, "node_modules/css-has-pseudo": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" @@ -5511,17 +6754,19 @@ } }, "node_modules/css-loader": { - "version": "6.7.1", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.7", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", - "semver": "^7.3.5" + "semver": "^7.5.4" }, "engines": { "node": ">= 12.13.0" @@ -5531,16 +6776,23 @@ "url": "https://opencollective.com/webpack" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/css-loader/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -5550,6 +6802,8 @@ }, "node_modules/css-minimizer-webpack-plugin": { "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", "license": "MIT", "dependencies": { "cssnano": "^5.0.6", @@ -5584,53 +6838,19 @@ } } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.11.0", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, + "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "node": ">=0.10.0" } }, "node_modules/css-prefers-color-scheme": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", "license": "CC0-1.0", "bin": { "css-prefers-color-scheme": "dist/cli.cjs" @@ -5644,6 +6864,8 @@ }, "node_modules/css-select": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -5658,10 +6880,14 @@ }, "node_modules/css-select-base-adapter": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", "license": "MIT" }, "node_modules/css-tree": { "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", "license": "MIT", "dependencies": { "mdn-data": "2.0.4", @@ -5671,8 +6897,19 @@ "node": ">=8.0.0" } }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/css-what": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "license": "BSD-2-Clause", "engines": { "node": ">= 6" @@ -5682,15 +6919,25 @@ } }, "node_modules/cssdb": { - "version": "6.6.3", - "license": "CC0-1.0", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz", + "integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ], + "license": "CC0-1.0" }, "node_modules/cssesc": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -5700,10 +6947,12 @@ } }, "node_modules/cssnano": { - "version": "5.1.11", + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", "license": "MIT", "dependencies": { - "cssnano-preset-default": "^5.2.11", + "cssnano-preset-default": "^5.2.14", "lilconfig": "^2.0.3", "yaml": "^1.10.2" }, @@ -5719,35 +6968,37 @@ } }, "node_modules/cssnano-preset-default": { - "version": "5.2.11", + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", "license": "MIT", "dependencies": { - "css-declaration-sorter": "^6.2.2", + "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", - "postcss-convert-values": "^5.1.2", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", "postcss-discard-comments": "^5.1.2", "postcss-discard-duplicates": "^5.1.0", "postcss-discard-empty": "^5.1.1", "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.5", - "postcss-merge-rules": "^5.1.2", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", "postcss-minify-font-values": "^5.1.0", "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.3", + "postcss-minify-params": "^5.1.4", "postcss-minify-selectors": "^5.2.1", "postcss-normalize-charset": "^5.1.0", "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.0", - "postcss-normalize-repeat-style": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", "postcss-normalize-string": "^5.1.0", "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", "postcss-normalize-url": "^5.1.0", "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.2", - "postcss-reduce-initial": "^5.1.0", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", "postcss-reduce-transforms": "^5.1.0", "postcss-svgo": "^5.1.0", "postcss-unique-selectors": "^5.1.1" @@ -5761,6 +7012,8 @@ }, "node_modules/cssnano-utils": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" @@ -5771,6 +7024,8 @@ }, "node_modules/csso": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", "license": "MIT", "dependencies": { "css-tree": "^1.1.2" @@ -5781,6 +7036,8 @@ }, "node_modules/csso/node_modules/css-tree": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "license": "MIT", "dependencies": { "mdn-data": "2.0.14", @@ -5792,14 +7049,29 @@ }, "node_modules/csso/node_modules/mdn-data": { "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "license": "CC0-1.0" }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/cssom": { "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", "license": "MIT" }, "node_modules/cssstyle": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "license": "MIT", "dependencies": { "cssom": "~0.3.6" @@ -5810,18 +7082,26 @@ }, "node_modules/cssstyle/node_modules/cssom": { "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "license": "MIT" }, "node_modules/csstype": { - "version": "3.1.1", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "license": "BSD-2-Clause" }, "node_modules/data-urls": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "license": "MIT", "dependencies": { "abab": "^2.0.3", @@ -5832,8 +7112,61 @@ "node": ">=10" } }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { - "version": "4.3.4", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -5848,19 +7181,59 @@ } }, "node_modules/decimal.js": { - "version": "10.3.1", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", "license": "MIT" }, "node_modules/dedent": { "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "license": "MIT" }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/deep-is": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "license": "MIT" }, "node_modules/deepmerge": { - "version": "4.2.2", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5868,6 +7241,8 @@ }, "node_modules/default-gateway": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "license": "BSD-2-Clause", "dependencies": { "execa": "^5.0.0" @@ -5876,17 +7251,39 @@ "node": ">= 10" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/define-properties": { - "version": "1.1.4", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "license": "MIT", "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -5897,12 +7294,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/defined": { - "version": "1.0.0", - "license": "MIT" - }, "node_modules/delayed-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -5910,6 +7305,8 @@ }, "node_modules/depd": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -5917,6 +7314,8 @@ }, "node_modules/destroy": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "license": "MIT", "engines": { "node": ">= 0.8", @@ -5925,6 +7324,8 @@ }, "node_modules/detect-newline": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "license": "MIT", "engines": { "node": ">=8" @@ -5932,10 +7333,14 @@ }, "node_modules/detect-node": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "license": "MIT" }, "node_modules/detect-port-alt": { "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", "license": "MIT", "dependencies": { "address": "^1.0.1", @@ -5951,6 +7356,8 @@ }, "node_modules/detect-port-alt/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -5958,29 +7365,20 @@ }, "node_modules/detect-port-alt/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/detective": { - "version": "5.2.1", - "license": "MIT", - "dependencies": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - }, - "bin": { - "detective": "bin/detective.js" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/didyoumean": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "license": "Apache-2.0" }, "node_modules/diff-sequences": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "license": "MIT", "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -5988,6 +7386,8 @@ }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "license": "MIT", "dependencies": { "path-type": "^4.0.0" @@ -5998,16 +7398,15 @@ }, "node_modules/dlv": { "version": "1.1.3", - "license": "MIT" - }, - "node_modules/dns-equal": { - "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", "license": "MIT" }, "node_modules/dns-packet": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -6017,6 +7416,8 @@ }, "node_modules/doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -6027,6 +7428,8 @@ }, "node_modules/dom-converter": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "license": "MIT", "dependencies": { "utila": "~0.4" @@ -6034,6 +7437,8 @@ }, "node_modules/dom-helpers": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.7", @@ -6042,6 +7447,8 @@ }, "node_modules/dom-serializer": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", @@ -6054,6 +7461,8 @@ }, "node_modules/domelementtype": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", @@ -6064,6 +7473,9 @@ }, "node_modules/domexception": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "deprecated": "Use your platform's native DOMException instead", "license": "MIT", "dependencies": { "webidl-conversions": "^5.0.0" @@ -6074,6 +7486,8 @@ }, "node_modules/domexception/node_modules/webidl-conversions": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", "license": "BSD-2-Clause", "engines": { "node": ">=8" @@ -6081,6 +7495,8 @@ }, "node_modules/domhandler": { "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" @@ -6094,6 +7510,8 @@ }, "node_modules/domutils": { "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", @@ -6106,6 +7524,8 @@ }, "node_modules/dot-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -6114,6 +7534,8 @@ }, "node_modules/dotenv": { "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", "license": "BSD-2-Clause", "engines": { "node": ">=10" @@ -6121,20 +7543,33 @@ }, "node_modules/dotenv-expand": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", "license": "BSD-2-Clause" }, "node_modules/duplexer": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" }, @@ -6146,12 +7581,15 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.559", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.559.tgz", - "integrity": "sha512-iS7KhLYCSJbdo3rUSkhDTVuFNCV34RKs2UaB9Ecr7VlqzjjWW//0nfsFF5dtDmyXlZQaDYYtID5fjtC/6lpRug==" + "version": "1.5.14", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.14.tgz", + "integrity": "sha512-bEfPECb3fJ15eaDnu9LEJ2vPGD6W1vt7vZleSVyFhYuMIKm3vz/g9lt7IvEzgdwj58RjbPKUF2rXTCN/UW47tQ==", + "license": "ISC" }, "node_modules/emittery": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "license": "MIT", "engines": { "node": ">=10" @@ -6162,10 +7600,14 @@ }, "node_modules/emoji-regex": { "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, "node_modules/emojis-list": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "license": "MIT", "engines": { "node": ">= 4" @@ -6173,15 +7615,18 @@ }, "node_modules/encodeurl": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/enhanced-resolve": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", - "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -6191,10 +7636,13 @@ } }, "node_modules/enquirer": { - "version": "2.3.6", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "license": "MIT", "dependencies": { - "ansi-colors": "^4.1.1" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8.6" @@ -6202,6 +7650,8 @@ }, "node_modules/entities": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" @@ -6209,6 +7659,8 @@ }, "node_modules/error-ex": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -6216,38 +7668,65 @@ }, "node_modules/error-stack-parser": { "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", "license": "MIT", "dependencies": { "stackframe": "^1.3.4" } }, "node_modules/es-abstract": { - "version": "1.20.1", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -6258,22 +7737,121 @@ }, "node_modules/es-array-method-boxes-properly": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", "license": "MIT" }, - "node_modules/es-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", - "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==" - }, - "node_modules/es-shim-unscopables": { + "node_modules/es-define-property": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "license": "MIT", "dependencies": { - "has": "^1.0.3" + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "license": "MIT", "dependencies": { "is-callable": "^1.1.4", @@ -6288,7 +7866,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -6296,23 +7876,31 @@ }, "node_modules/escape-html": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/escape-string-regexp": { - "version": "1.0.5", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/escodegen": { - "version": "2.0.0", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" + "esutils": "^2.0.2" }, "bin": { "escodegen": "bin/escodegen.js", @@ -6325,50 +7913,20 @@ "source-map": "~0.6.1" } }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "license": "MIT", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" + "node": ">=0.10.0" } }, "node_modules/eslint": { "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "license": "MIT", "dependencies": { "@babel/code-frame": "7.12.11", @@ -6424,6 +7982,8 @@ }, "node_modules/eslint-config-airbnb": { "version": "18.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", + "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", "dev": true, "license": "MIT", "dependencies": { @@ -6444,6 +8004,8 @@ }, "node_modules/eslint-config-airbnb-base": { "version": "14.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", + "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", "dev": true, "license": "MIT", "dependencies": { @@ -6460,55 +8022,75 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "license": "MIT", "dependencies": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-module-utils": { - "version": "2.7.3", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz", + "integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==", "license": "MIT", "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "engines": { "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/eslint-module-utils/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import": { - "version": "2.26.0", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", + "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", "license": "MIT", "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.9.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -6518,14 +8100,18 @@ } }, "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -6534,12 +8120,10 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "license": "MIT" - }, "node_modules/eslint-plugin-jest": { "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", "license": "MIT", "dependencies": { "@typescript-eslint/experimental-utils": "^5.0.0" @@ -6561,68 +8145,71 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.5.1", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.0.tgz", + "integrity": "sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.16.3", - "aria-query": "^4.2.2", - "array-includes": "^3.1.4", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.3.5", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.7", + "aria-query": "~5.1.3", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.2.1", - "language-tags": "^1.0.5", - "minimatch": "^3.0.4" + "es-iterator-helpers": "^1.0.19", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.0" }, "engines": { "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { - "version": "4.2.2", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "node_modules/eslint-plugin-react": { - "version": "7.30.0", + "version": "7.35.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz", + "integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==", "license": "MIT", "dependencies": { - "array-includes": "^3.1.5", - "array.prototype.flatmap": "^1.3.0", + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.5", - "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.1", - "object.values": "^1.1.5", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.7" + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.5.0", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "license": "MIT", "engines": { "node": ">=10" @@ -6633,6 +8220,8 @@ }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -6642,21 +8231,29 @@ } }, "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.3", + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "license": "MIT", "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/eslint-plugin-testing-library": { - "version": "5.5.1", + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", + "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^5.13.0" + "@typescript-eslint/utils": "^5.58.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0", @@ -6668,6 +8265,8 @@ }, "node_modules/eslint-scope": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -6679,6 +8278,8 @@ }, "node_modules/eslint-scope/node_modules/estraverse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -6686,6 +8287,8 @@ }, "node_modules/eslint-utils": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "license": "MIT", "dependencies": { "eslint-visitor-keys": "^1.1.0" @@ -6699,6 +8302,8 @@ }, "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "license": "Apache-2.0", "engines": { "node": ">=4" @@ -6706,20 +8311,24 @@ }, "node_modules/eslint-visitor-keys": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "license": "Apache-2.0", "engines": { "node": ">=10" } }, "node_modules/eslint-webpack-plugin": { - "version": "3.1.1", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", "license": "MIT", "dependencies": { - "@types/eslint": "^7.28.2", - "jest-worker": "^27.3.1", - "micromatch": "^4.0.4", + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", "normalize-path": "^3.0.0", - "schema-utils": "^3.1.1" + "schema-utils": "^4.0.0" }, "engines": { "node": ">= 12.13.0" @@ -6733,8 +8342,48 @@ "webpack": "^5.0.0" } }, + "node_modules/eslint-webpack-plugin/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/eslint/node_modules/@babel/code-frame": { "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "license": "MIT", "dependencies": { "@babel/highlight": "^7.10.4" @@ -6742,6 +8391,8 @@ }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -6755,6 +8406,8 @@ }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -6769,6 +8422,8 @@ }, "node_modules/eslint/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -6779,20 +8434,14 @@ }, "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/globals": { - "version": "13.15.0", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -6806,18 +8455,18 @@ }, "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/eslint/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -6827,6 +8476,8 @@ }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6837,6 +8488,8 @@ }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -6847,6 +8500,8 @@ }, "node_modules/espree": { "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "license": "BSD-2-Clause", "dependencies": { "acorn": "^7.4.0", @@ -6859,6 +8514,8 @@ }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "license": "Apache-2.0", "engines": { "node": ">=4" @@ -6866,6 +8523,8 @@ }, "node_modules/esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -6876,7 +8535,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -6887,6 +8548,8 @@ }, "node_modules/esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -6897,6 +8560,8 @@ }, "node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -6904,10 +8569,14 @@ }, "node_modules/estree-walker": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -6915,6 +8584,8 @@ }, "node_modules/etag": { "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -6922,10 +8593,14 @@ }, "node_modules/eventemitter3": { "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, "node_modules/events": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" @@ -6933,6 +8608,8 @@ }, "node_modules/execa": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -6954,12 +8631,16 @@ }, "node_modules/exit": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "engines": { "node": ">= 0.8.0" } }, "node_modules/expect": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -6975,6 +8656,7 @@ "version": "4.19.2", "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -7012,12 +8694,10 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "license": "MIT" - }, "node_modules/express/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -7025,32 +8705,20 @@ }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "license": "MIT" - }, - "node_modules/express/node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.2.11", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -7065,14 +8733,26 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", "license": "MIT" }, "node_modules/fastq": { - "version": "1.13.0", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -7080,6 +8760,8 @@ }, "node_modules/faye-websocket": { "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" @@ -7089,7 +8771,9 @@ } }, "node_modules/fb-watchman": { - "version": "2.0.1", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" @@ -7097,6 +8781,8 @@ }, "node_modules/file-entry-cache": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" @@ -7107,6 +8793,8 @@ }, "node_modules/file-loader": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", @@ -7123,8 +8811,28 @@ "webpack": "^4.0.0 || ^5.0.0" } }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/filelist": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "license": "Apache-2.0", "dependencies": { "minimatch": "^5.0.1" @@ -7132,13 +8840,17 @@ }, "node_modules/filelist/node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.0", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -7149,13 +8861,17 @@ }, "node_modules/filesize": { "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 0.4.0" } }, "node_modules/fill-range": { - "version": "7.0.1", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -7166,6 +8882,8 @@ }, "node_modules/finalhandler": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -7182,6 +8900,8 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -7189,10 +8909,14 @@ }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/find-cache-dir": { "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "license": "MIT", "dependencies": { "commondir": "^1.0.1", @@ -7208,23 +8932,31 @@ }, "node_modules/find-root": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "license": "MIT" }, "node_modules/find-up": { - "version": "2.1.0", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "license": "MIT", "dependencies": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/flat-cache": { - "version": "3.0.4", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "license": "MIT", "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { @@ -7232,19 +8964,22 @@ } }, "node_modules/flatted": { - "version": "3.2.5", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -7254,8 +8989,47 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.2", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.8.3", @@ -7293,6 +9067,8 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -7306,6 +9082,8 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -7320,6 +9098,8 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -7330,10 +9110,14 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", @@ -7348,6 +9132,8 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", @@ -7361,6 +9147,8 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -7368,6 +9156,8 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.4", @@ -7383,12 +9173,10 @@ } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -7398,6 +9186,8 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -7408,6 +9198,8 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "license": "MIT", "engines": { "node": ">=6" @@ -7415,6 +9207,8 @@ }, "node_modules/form-data": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -7427,24 +9221,30 @@ }, "node_modules/forwarded": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fraction.js": { - "version": "4.2.0", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "license": "MIT", "engines": { "node": "*" }, "funding": { "type": "patreon", - "url": "https://www.patreon.com/infusion" + "url": "https://github.com/sponsors/rawify" } }, "node_modules/fresh": { "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -7452,6 +9252,8 @@ }, "node_modules/fs-extra": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -7463,18 +9265,23 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.3", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", "license": "Unlicense" }, "node_modules/fs.realpath": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -7484,17 +9291,24 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "license": "MIT" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { - "version": "1.1.5", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -7505,10 +9319,14 @@ }, "node_modules/functional-red-black-tree": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "license": "MIT" }, "node_modules/functions-have-names": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7516,6 +9334,8 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -7523,18 +9343,27 @@ }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-intrinsic": { - "version": "1.1.1", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7542,10 +9371,14 @@ }, "node_modules/get-own-enumerable-property-symbols": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", "license": "ISC" }, "node_modules/get-package-type": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "license": "MIT", "engines": { "node": ">=8.0.0" @@ -7553,6 +9386,8 @@ }, "node_modules/get-stream": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "license": "MIT", "engines": { "node": ">=10" @@ -7562,11 +9397,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.0", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -7577,6 +9415,9 @@ }, "node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -7595,6 +9436,8 @@ }, "node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -7606,10 +9449,13 @@ "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" }, "node_modules/global-modules": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "license": "MIT", "dependencies": { "global-prefix": "^3.0.0" @@ -7620,6 +9466,8 @@ }, "node_modules/global-prefix": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "license": "MIT", "dependencies": { "ini": "^1.3.5", @@ -7632,6 +9480,8 @@ }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -7642,13 +9492,33 @@ }, "node_modules/globals": { "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "license": "MIT", "dependencies": { "array-union": "^2.1.0", @@ -7666,19 +9536,42 @@ } }, "node_modules/globby/node_modules/ignore": { - "version": "5.2.0", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "license": "MIT" }, "node_modules/gzip-size": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "license": "MIT", "dependencies": { "duplexer": "^0.1.2" @@ -7692,24 +9585,20 @@ }, "node_modules/handle-thing": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "license": "MIT" }, "node_modules/harmony-reflect": { "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", "license": "(Apache-2.0 OR MPL-1.1)" }, - "node_modules/has": { - "version": "1.0.3", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7717,16 +9606,32 @@ }, "node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7734,6 +9639,8 @@ }, "node_modules/has-symbols": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -7743,10 +9650,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -7755,8 +9664,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "license": "MIT", "bin": { "he": "bin/he" @@ -7764,6 +9687,8 @@ }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" @@ -7771,10 +9696,14 @@ }, "node_modules/hoist-non-react-statics/node_modules/react-is": { "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, "node_modules/hoopy": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", "license": "MIT", "engines": { "node": ">= 6.0.0" @@ -7782,6 +9711,8 @@ }, "node_modules/hpack.js": { "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "license": "MIT", "dependencies": { "inherits": "^2.0.1", @@ -7790,8 +9721,16 @@ "wbuf": "^1.1.0" } }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.7", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", @@ -7803,8 +9742,16 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" @@ -7812,6 +9759,8 @@ }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "license": "MIT", "dependencies": { "whatwg-encoding": "^1.0.5" @@ -7821,15 +9770,31 @@ } }, "node_modules/html-entities": { - "version": "2.3.3", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], "license": "MIT" }, "node_modules/html-escaper": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "license": "MIT" }, "node_modules/html-minifier-terser": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", "license": "MIT", "dependencies": { "camel-case": "^4.1.2", @@ -7848,7 +9813,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.0", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", "license": "MIT", "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -7865,11 +9832,22 @@ "url": "https://opencollective.com/html-webpack-plugin" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/htmlparser2": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -7887,10 +9865,14 @@ }, "node_modules/http-deceiver": { "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", "license": "MIT" }, "node_modules/http-errors": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "license": "MIT", "dependencies": { "depd": "2.0.0", @@ -7904,11 +9886,15 @@ } }, "node_modules/http-parser-js": { - "version": "0.5.6", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", "license": "MIT" }, "node_modules/http-proxy": { "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "license": "MIT", "dependencies": { "eventemitter3": "^4.0.0", @@ -7921,6 +9907,8 @@ }, "node_modules/http-proxy-agent": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "license": "MIT", "dependencies": { "@tootallnate/once": "1", @@ -7933,6 +9921,8 @@ }, "node_modules/http-proxy-middleware": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", @@ -7955,6 +9945,8 @@ }, "node_modules/https-proxy-agent": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "license": "MIT", "dependencies": { "agent-base": "6", @@ -7966,6 +9958,8 @@ }, "node_modules/human-signals": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -7973,6 +9967,8 @@ }, "node_modules/iconv-lite": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -7983,6 +9979,8 @@ }, "node_modules/icss-utils": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" @@ -7992,11 +9990,15 @@ } }, "node_modules/idb": { - "version": "6.1.5", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", "license": "ISC" }, "node_modules/identity-obj-proxy": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", "license": "MIT", "dependencies": { "harmony-reflect": "^1.4.6" @@ -8007,13 +10009,17 @@ }, "node_modules/ignore": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/immer": { - "version": "9.0.14", + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", "license": "MIT", "funding": { "type": "opencollective", @@ -8022,6 +10028,8 @@ }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -8035,7 +10043,9 @@ } }, "node_modules/import-local": { - "version": "3.1.0", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", @@ -8053,6 +10063,8 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "license": "MIT", "engines": { "node": ">=0.8.19" @@ -8060,6 +10072,9 @@ }, "node_modules/inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -8068,18 +10083,24 @@ }, "node_modules/inherits": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC" }, "node_modules/internal-slot": { - "version": "1.0.3", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -8088,6 +10109,8 @@ }, "node_modules/intl-messageformat": { "version": "9.13.0", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz", + "integrity": "sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==", "license": "BSD-3-Clause", "dependencies": { "@formatjs/ecma402-abstract": "1.11.4", @@ -8097,18 +10120,71 @@ } }, "node_modules/ipaddr.js": { - "version": "2.0.1", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "license": "MIT", "engines": { "node": ">= 10" } }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "license": "MIT" }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" @@ -8119,6 +10195,8 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -8129,6 +10207,8 @@ }, "node_modules/is-boolean-object": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "license": "MIT", "dependencies": { "call-bind": "^1.0.2", @@ -8142,7 +10222,9 @@ } }, "node_modules/is-callable": { - "version": "1.2.4", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -8152,10 +10234,30 @@ } }, "node_modules/is-core-module": { - "version": "2.9.0", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "license": "MIT", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "license": "MIT", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8163,6 +10265,8 @@ }, "node_modules/is-date-object": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" @@ -8176,6 +10280,8 @@ }, "node_modules/is-docker": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "license": "MIT", "bin": { "is-docker": "cli.js" @@ -8189,13 +10295,29 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" @@ -8203,13 +10325,32 @@ }, "node_modules/is-generator-fn": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -8218,12 +10359,28 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-module": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", "license": "MIT" }, "node_modules/is-negative-zero": { - "version": "2.0.2", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -8234,6 +10391,8 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "license": "MIT", "engines": { "node": ">=0.12.0" @@ -8241,6 +10400,8 @@ }, "node_modules/is-number-object": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" @@ -8254,13 +10415,26 @@ }, "node_modules/is-obj": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "license": "MIT", "engines": { "node": ">=10" @@ -8271,10 +10445,14 @@ }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "license": "MIT" }, "node_modules/is-regex": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "license": "MIT", "dependencies": { "call-bind": "^1.0.2", @@ -8289,6 +10467,8 @@ }, "node_modules/is-regexp": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8296,16 +10476,35 @@ }, "node_modules/is-root": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8313,6 +10512,8 @@ }, "node_modules/is-stream": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", "engines": { "node": ">=8" @@ -8323,6 +10524,8 @@ }, "node_modules/is-string": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" @@ -8336,6 +10539,8 @@ }, "node_modules/is-symbol": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" @@ -8347,12 +10552,43 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "license": "MIT" }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "license": "MIT", "dependencies": { "call-bind": "^1.0.2" @@ -8361,8 +10597,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-wsl": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "license": "MIT", "dependencies": { "is-docker": "^2.0.0" @@ -8372,22 +10626,30 @@ } }, "node_modules/isarray": { - "version": "1.0.0", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", @@ -8401,26 +10663,59 @@ } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-report/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -8431,6 +10726,8 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", @@ -8441,8 +10738,19 @@ "node": ">=10" } }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/istanbul-reports": { - "version": "3.1.4", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", @@ -8452,14 +10760,44 @@ "node": ">=8" } }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jake": { - "version": "10.8.5", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" + "filelist": "^1.0.4", + "minimatch": "^3.1.2" }, "bin": { "jake": "bin/cli.js" @@ -8470,6 +10808,8 @@ }, "node_modules/jake/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -8483,6 +10823,8 @@ }, "node_modules/jake/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8497,6 +10839,8 @@ }, "node_modules/jake/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -8507,10 +10851,14 @@ }, "node_modules/jake/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jake/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -8518,6 +10866,8 @@ }, "node_modules/jake/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -8528,6 +10878,8 @@ }, "node_modules/jest": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "license": "MIT", "dependencies": { "@jest/core": "^27.5.1", @@ -8551,6 +10903,8 @@ }, "node_modules/jest-changed-files": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -8563,6 +10917,8 @@ }, "node_modules/jest-circus": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", @@ -8591,6 +10947,8 @@ }, "node_modules/jest-circus/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -8604,6 +10962,8 @@ }, "node_modules/jest-circus/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8618,6 +10978,8 @@ }, "node_modules/jest-circus/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -8628,10 +10990,14 @@ }, "node_modules/jest-circus/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-circus/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -8639,6 +11005,8 @@ }, "node_modules/jest-circus/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -8649,6 +11017,8 @@ }, "node_modules/jest-cli": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", "license": "MIT", "dependencies": { "@jest/core": "^27.5.1", @@ -8681,6 +11051,8 @@ }, "node_modules/jest-cli/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -8694,6 +11066,8 @@ }, "node_modules/jest-cli/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8708,6 +11082,8 @@ }, "node_modules/jest-cli/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -8718,10 +11094,14 @@ }, "node_modules/jest-cli/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-cli/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -8729,6 +11109,8 @@ }, "node_modules/jest-cli/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -8739,6 +11121,8 @@ }, "node_modules/jest-config": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", "license": "MIT", "dependencies": { "@babel/core": "^7.8.0", @@ -8780,6 +11164,8 @@ }, "node_modules/jest-config/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -8793,6 +11179,8 @@ }, "node_modules/jest-config/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8807,6 +11195,8 @@ }, "node_modules/jest-config/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -8817,10 +11207,14 @@ }, "node_modules/jest-config/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-config/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -8828,6 +11222,8 @@ }, "node_modules/jest-config/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -8838,6 +11234,8 @@ }, "node_modules/jest-diff": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -8851,6 +11249,8 @@ }, "node_modules/jest-diff/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -8864,6 +11264,8 @@ }, "node_modules/jest-diff/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8878,6 +11280,8 @@ }, "node_modules/jest-diff/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -8888,10 +11292,14 @@ }, "node_modules/jest-diff/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-diff/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -8899,6 +11307,8 @@ }, "node_modules/jest-diff/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -8909,6 +11319,8 @@ }, "node_modules/jest-docblock": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" @@ -8919,6 +11331,8 @@ }, "node_modules/jest-each": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -8933,6 +11347,8 @@ }, "node_modules/jest-each/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -8946,6 +11362,8 @@ }, "node_modules/jest-each/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -8960,6 +11378,8 @@ }, "node_modules/jest-each/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -8970,10 +11390,14 @@ }, "node_modules/jest-each/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-each/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -8981,6 +11405,8 @@ }, "node_modules/jest-each/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -8991,6 +11417,8 @@ }, "node_modules/jest-environment-jsdom": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", @@ -9007,6 +11435,8 @@ }, "node_modules/jest-environment-node": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", @@ -9022,6 +11452,8 @@ }, "node_modules/jest-get-type": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "license": "MIT", "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -9029,6 +11461,8 @@ }, "node_modules/jest-haste-map": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -9053,6 +11487,8 @@ }, "node_modules/jest-jasmine2": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", @@ -9079,6 +11515,8 @@ }, "node_modules/jest-jasmine2/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9092,6 +11530,8 @@ }, "node_modules/jest-jasmine2/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9106,6 +11546,8 @@ }, "node_modules/jest-jasmine2/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9116,10 +11558,14 @@ }, "node_modules/jest-jasmine2/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-jasmine2/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -9127,6 +11573,8 @@ }, "node_modules/jest-jasmine2/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9137,6 +11585,8 @@ }, "node_modules/jest-leak-detector": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", "license": "MIT", "dependencies": { "jest-get-type": "^27.5.1", @@ -9148,6 +11598,8 @@ }, "node_modules/jest-matcher-utils": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -9161,6 +11613,8 @@ }, "node_modules/jest-matcher-utils/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9174,6 +11628,8 @@ }, "node_modules/jest-matcher-utils/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9188,6 +11644,8 @@ }, "node_modules/jest-matcher-utils/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9198,10 +11656,14 @@ }, "node_modules/jest-matcher-utils/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-matcher-utils/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -9209,6 +11671,8 @@ }, "node_modules/jest-matcher-utils/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9219,6 +11683,8 @@ }, "node_modules/jest-message-util": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", @@ -9237,6 +11703,8 @@ }, "node_modules/jest-message-util/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9250,6 +11718,8 @@ }, "node_modules/jest-message-util/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9264,6 +11734,8 @@ }, "node_modules/jest-message-util/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9274,10 +11746,14 @@ }, "node_modules/jest-message-util/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-message-util/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -9285,6 +11761,8 @@ }, "node_modules/jest-message-util/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9295,6 +11773,8 @@ }, "node_modules/jest-mock": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -9305,7 +11785,9 @@ } }, "node_modules/jest-pnp-resolver": { - "version": "1.2.2", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "license": "MIT", "engines": { "node": ">=6" @@ -9321,6 +11803,8 @@ }, "node_modules/jest-regex-util": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "license": "MIT", "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -9328,6 +11812,8 @@ }, "node_modules/jest-resolve": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -9347,6 +11833,8 @@ }, "node_modules/jest-resolve-dependencies": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -9359,6 +11847,8 @@ }, "node_modules/jest-resolve/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9372,6 +11862,8 @@ }, "node_modules/jest-resolve/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9386,6 +11878,8 @@ }, "node_modules/jest-resolve/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9396,10 +11890,14 @@ }, "node_modules/jest-resolve/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-resolve/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -9407,6 +11905,8 @@ }, "node_modules/jest-resolve/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9417,6 +11917,8 @@ }, "node_modules/jest-runner": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", "license": "MIT", "dependencies": { "@jest/console": "^27.5.1", @@ -9447,6 +11949,8 @@ }, "node_modules/jest-runner/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9460,6 +11964,8 @@ }, "node_modules/jest-runner/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9474,6 +11980,8 @@ }, "node_modules/jest-runner/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9484,10 +11992,14 @@ }, "node_modules/jest-runner/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-runner/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -9495,6 +12007,8 @@ }, "node_modules/jest-runner/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9505,6 +12019,8 @@ }, "node_modules/jest-runtime": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", "license": "MIT", "dependencies": { "@jest/environment": "^27.5.1", @@ -9536,6 +12052,8 @@ }, "node_modules/jest-runtime/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9549,6 +12067,8 @@ }, "node_modules/jest-runtime/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9563,6 +12083,8 @@ }, "node_modules/jest-runtime/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9573,10 +12095,14 @@ }, "node_modules/jest-runtime/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-runtime/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -9584,6 +12110,8 @@ }, "node_modules/jest-runtime/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9594,6 +12122,8 @@ }, "node_modules/jest-serializer": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -9605,6 +12135,8 @@ }, "node_modules/jest-snapshot": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", "license": "MIT", "dependencies": { "@babel/core": "^7.7.2", @@ -9636,6 +12168,8 @@ }, "node_modules/jest-snapshot/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9649,6 +12183,8 @@ }, "node_modules/jest-snapshot/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9663,6 +12199,8 @@ }, "node_modules/jest-snapshot/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9673,22 +12211,24 @@ }, "node_modules/jest-snapshot/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-snapshot/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -9698,6 +12238,8 @@ }, "node_modules/jest-snapshot/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9708,6 +12250,8 @@ }, "node_modules/jest-util": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -9723,6 +12267,8 @@ }, "node_modules/jest-util/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9736,6 +12282,8 @@ }, "node_modules/jest-util/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9750,6 +12298,8 @@ }, "node_modules/jest-util/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9760,10 +12310,14 @@ }, "node_modules/jest-util/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-util/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -9771,6 +12325,8 @@ }, "node_modules/jest-util/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9781,6 +12337,8 @@ }, "node_modules/jest-validate": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", "license": "MIT", "dependencies": { "@jest/types": "^27.5.1", @@ -9796,6 +12354,8 @@ }, "node_modules/jest-validate/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9809,6 +12369,8 @@ }, "node_modules/jest-validate/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9823,6 +12385,8 @@ }, "node_modules/jest-validate/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9833,10 +12397,14 @@ }, "node_modules/jest-validate/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-validate/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -9844,6 +12412,8 @@ }, "node_modules/jest-validate/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9854,6 +12424,8 @@ }, "node_modules/jest-watch-typeahead": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.1", @@ -9872,14 +12444,16 @@ } }, "node_modules/jest-watch-typeahead/node_modules/@jest/console": { - "version": "28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", "license": "MIT", "dependencies": { - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^28.1.1", - "jest-util": "^28.1.1", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0" }, "engines": { @@ -9888,17 +12462,21 @@ }, "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { - "version": "28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", "license": "MIT", "dependencies": { - "@jest/console": "^28.1.1", - "@jest/types": "^28.1.1", + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -9907,10 +12485,12 @@ } }, "node_modules/jest-watch-typeahead/node_modules/@jest/types": { - "version": "28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "license": "MIT", "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -9922,7 +12502,9 @@ } }, "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { - "version": "17.0.10", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "license": "MIT", "dependencies": { "@types/yargs-parser": "*" @@ -9930,6 +12512,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9943,6 +12527,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -9957,6 +12543,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9967,10 +12555,14 @@ }, "node_modules/jest-watch-typeahead/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-watch-typeahead/node_modules/emittery": { "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", "license": "MIT", "engines": { "node": ">=12" @@ -9981,22 +12573,26 @@ }, "node_modules/jest-watch-typeahead/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { - "version": "28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.1", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -10006,6 +12602,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "license": "MIT", "engines": { "node": ">=8" @@ -10013,16 +12611,20 @@ }, "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", "license": "MIT", "engines": { "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-watch-typeahead/node_modules/jest-util": { - "version": "28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "license": "MIT", "dependencies": { - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -10034,16 +12636,18 @@ } }, "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { - "version": "28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", "license": "MIT", "dependencies": { - "@jest/test-result": "^28.1.1", - "@jest/types": "^28.1.1", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.10.2", - "jest-util": "^28.1.1", + "jest-util": "^28.1.3", "string-length": "^4.0.1" }, "engines": { @@ -10052,6 +12656,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "license": "MIT", "dependencies": { "char-regex": "^1.0.2", @@ -10063,6 +12669,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -10072,10 +12680,12 @@ } }, "node_modules/jest-watch-typeahead/node_modules/pretty-format": { - "version": "28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "license": "MIT", "dependencies": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -10086,6 +12696,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "license": "MIT", "engines": { "node": ">=10" @@ -10094,12 +12706,10 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-watch-typeahead/node_modules/react-is": { - "version": "18.1.0", - "license": "MIT" - }, "node_modules/jest-watch-typeahead/node_modules/slash": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "license": "MIT", "engines": { "node": ">=12" @@ -10110,6 +12720,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/string-length": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", "license": "MIT", "dependencies": { "char-regex": "^2.0.0", @@ -10124,13 +12736,17 @@ }, "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", "license": "MIT", "engines": { "node": ">=12.20" } }, "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { - "version": "7.0.1", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -10144,6 +12760,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "license": "MIT", "engines": { "node": ">=12" @@ -10154,6 +12772,8 @@ }, "node_modules/jest-watch-typeahead/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10164,6 +12784,8 @@ }, "node_modules/jest-watcher": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", "license": "MIT", "dependencies": { "@jest/test-result": "^27.5.1", @@ -10180,6 +12802,8 @@ }, "node_modules/jest-watcher/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -10193,6 +12817,8 @@ }, "node_modules/jest-watcher/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -10207,6 +12833,8 @@ }, "node_modules/jest-watcher/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -10217,10 +12845,14 @@ }, "node_modules/jest-watcher/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/jest-watcher/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -10228,6 +12860,8 @@ }, "node_modules/jest-watcher/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10238,6 +12872,8 @@ }, "node_modules/jest-worker": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -10250,6 +12886,8 @@ }, "node_modules/jest-worker/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -10257,6 +12895,8 @@ }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10268,12 +12908,25 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-tokens": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/js-yaml": { "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "license": "MIT", "dependencies": { "argparse": "^1.0.7", @@ -10285,6 +12938,8 @@ }, "node_modules/jsdom": { "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "license": "MIT", "dependencies": { "abab": "^2.0.5", @@ -10328,7 +12983,9 @@ } }, "node_modules/jsdom/node_modules/acorn": { - "version": "8.7.1", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -10339,6 +12996,8 @@ }, "node_modules/jsesc": { "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -10347,26 +13006,41 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "license": "MIT" }, "node_modules/json-schema": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/json-schema-traverse": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -10376,6 +13050,8 @@ }, "node_modules/jsonfile": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -10384,26 +13060,66 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "license": "MIT", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath/node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/jsonpointer": { - "version": "5.0.0", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/jsx-ast-utils": { - "version": "3.3.0", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "license": "MIT", "dependencies": { - "array-includes": "^3.1.4", - "object.assign": "^4.1.2" + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" }, "engines": { "node": ">=4.0" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10411,31 +13127,54 @@ }, "node_modules/kleur": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/klona": { - "version": "2.0.5", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/language-subtag-registry": { - "version": "0.3.21", - "license": "ODC-By-1.0" + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "license": "CC0-1.0" }, "node_modules/language-tags": { - "version": "1.0.5", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "license": "MIT", "dependencies": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/launch-editor": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" } }, "node_modules/leven": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "license": "MIT", "engines": { "node": ">=6" @@ -10443,6 +13182,8 @@ }, "node_modules/levn": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", @@ -10453,7 +13194,9 @@ } }, "node_modules/lilconfig": { - "version": "2.0.5", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "license": "MIT", "engines": { "node": ">=10" @@ -10461,10 +13204,14 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, "node_modules/loader-runner": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "license": "MIT", "engines": { "node": ">=6.11.5" @@ -10474,6 +13221,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -10484,46 +13232,63 @@ } }, "node_modules/locate-path": { - "version": "2.0.0", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "license": "MIT", "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/lodash": { "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "license": "MIT" }, "node_modules/lodash.sortby": { "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "license": "MIT" }, "node_modules/lodash.truncate": { "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "license": "MIT" }, "node_modules/lodash.uniq": { "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -10534,23 +13299,26 @@ }, "node_modules/lower-case": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/lru-cache": { - "version": "6.0.0", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "license": "ISC", "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/magic-string": { "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", "license": "MIT", "dependencies": { "sourcemap-codec": "^1.4.8" @@ -10558,6 +13326,8 @@ }, "node_modules/make-dir": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "license": "MIT", "dependencies": { "semver": "^6.0.0" @@ -10571,6 +13341,8 @@ }, "node_modules/makeerror": { "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" @@ -10578,21 +13350,26 @@ }, "node_modules/mdn-data": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", "license": "CC0-1.0" }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/memfs": { - "version": "3.4.4", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "license": "Unlicense", "dependencies": { - "fs-monkey": "1.0.3" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" @@ -10600,14 +13377,20 @@ }, "node_modules/merge-descriptors": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "license": "MIT" }, "node_modules/merge-stream": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "license": "MIT", "engines": { "node": ">= 8" @@ -10615,16 +13398,20 @@ }, "node_modules/methods": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.5", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -10633,6 +13420,8 @@ }, "node_modules/mime": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "license": "MIT", "bin": { "mime": "cli.js" @@ -10643,6 +13432,8 @@ }, "node_modules/mime-db": { "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -10650,6 +13441,8 @@ }, "node_modules/mime-types": { "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -10660,16 +13453,21 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/mini-css-extract-plugin": { - "version": "2.6.0", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.1.tgz", + "integrity": "sha512-+Vyi+GCCOHnrJ2VPS+6aPoXN2k2jgUzDRhTFLjjTBn23qyXJXkjUWQgTL+mXpF5/A8ixLdCc6kWsoeOjKGejKQ==", "license": "MIT", "dependencies": { - "schema-utils": "^4.0.0" + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" }, "engines": { "node": ">= 12.13.0" @@ -10682,57 +13480,16 @@ "webpack": "^5.0.0" } }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.11.0", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "license": "ISC" }, "node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -10742,11 +13499,27 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "license": "MIT" + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } }, "node_modules/mkdirp": { "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "license": "MIT", "dependencies": { "minimist": "^1.2.6" @@ -10757,10 +13530,14 @@ }, "node_modules/ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", @@ -10770,6 +13547,17 @@ "multicast-dns": "cli.js" } }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -10780,6 +13568,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -10789,10 +13578,20 @@ }, "node_modules/natural-compare": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -10800,10 +13599,14 @@ }, "node_modules/neo-async": { "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "license": "MIT" }, "node_modules/no-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "license": "MIT", "dependencies": { "lower-case": "^2.0.2", @@ -10812,6 +13615,8 @@ }, "node_modules/node-forge": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" @@ -10819,15 +13624,20 @@ }, "node_modules/node-int64": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10835,6 +13645,8 @@ }, "node_modules/normalize-range": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10842,6 +13654,8 @@ }, "node_modules/normalize-url": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "license": "MIT", "engines": { "node": ">=10" @@ -10852,6 +13666,8 @@ }, "node_modules/npm-run-path": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "license": "MIT", "dependencies": { "path-key": "^3.0.0" @@ -10862,6 +13678,8 @@ }, "node_modules/nth-check": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" @@ -10871,11 +13689,15 @@ } }, "node_modules/nwsapi": { - "version": "2.2.0", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", + "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10883,32 +13705,59 @@ }, "node_modules/object-hash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/object-inspect": { - "version": "1.12.2", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { - "version": "4.1.2", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -10919,24 +13768,29 @@ } }, "node_modules/object.entries": { - "version": "1.1.5", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.5", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -10946,13 +13800,18 @@ } }, "node_modules/object.getownpropertydescriptors": { - "version": "2.1.4", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz", + "integrity": "sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==", "license": "MIT", "dependencies": { - "array.prototype.reduce": "^1.0.4", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.1" + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "gopd": "^1.0.1", + "safe-array-concat": "^1.1.2" }, "engines": { "node": ">= 0.8" @@ -10961,24 +13820,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.hasown": { - "version": "1.1.1", + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "license": "MIT", "dependencies": { - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.4" } }, "node_modules/object.values": { - "version": "1.1.5", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -10989,10 +13853,14 @@ }, "node_modules/obuf": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "license": "MIT" }, "node_modules/on-finished": { "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -11003,6 +13871,8 @@ }, "node_modules/on-headers": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -11010,6 +13880,8 @@ }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" @@ -11017,6 +13889,8 @@ }, "node_modules/onetime": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -11029,7 +13903,9 @@ } }, "node_modules/open": { - "version": "8.4.0", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", @@ -11044,7 +13920,9 @@ } }, "node_modules/optionator": { - "version": "0.9.1", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "license": "MIT", "dependencies": { "deep-is": "^0.1.3", @@ -11052,34 +13930,43 @@ "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/p-limit": { - "version": "1.3.0", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "license": "MIT", "dependencies": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "2.0.0", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "license": "MIT", "dependencies": { - "p-limit": "^1.1.0" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/p-retry": { "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "license": "MIT", "dependencies": { "@types/retry": "0.12.0", @@ -11090,14 +13977,24 @@ } }, "node_modules/p-try": { - "version": "1.0.0", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "license": "BlueOak-1.0.0" + }, "node_modules/param-case": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "license": "MIT", "dependencies": { "dot-case": "^3.0.4", @@ -11106,6 +14003,8 @@ }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -11116,6 +14015,8 @@ }, "node_modules/parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -11132,10 +14033,14 @@ }, "node_modules/parse5": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "license": "MIT" }, "node_modules/parseurl": { "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -11143,6 +14048,8 @@ }, "node_modules/pascal-case": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -11150,14 +14057,18 @@ } }, "node_modules/path-exists": { - "version": "3.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11165,6 +14076,8 @@ }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" @@ -11172,14 +14085,42 @@ }, "node_modules/path-parse": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/path-to-regexp": { "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "license": "MIT", "engines": { "node": ">=8" @@ -11187,14 +14128,20 @@ }, "node_modules/performance-now": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -11203,8 +14150,19 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pirates": { - "version": "4.0.5", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "license": "MIT", "engines": { "node": ">= 6" @@ -11212,6 +14170,8 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "license": "MIT", "dependencies": { "find-up": "^4.0.0" @@ -11220,66 +14180,10 @@ "node": ">=8" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-try": { - "version": "2.2.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/pkg-up": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "license": "MIT", "dependencies": { "find-up": "^3.0.0" @@ -11290,6 +14194,8 @@ }, "node_modules/pkg-up/node_modules/find-up": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "license": "MIT", "dependencies": { "locate-path": "^3.0.0" @@ -11300,6 +14206,8 @@ }, "node_modules/pkg-up/node_modules/locate-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "license": "MIT", "dependencies": { "p-locate": "^3.0.0", @@ -11309,21 +14217,10 @@ "node": ">=6" } }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pkg-up/node_modules/p-locate": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "license": "MIT", "dependencies": { "p-limit": "^2.0.0" @@ -11332,17 +14229,28 @@ "node": ">=6" } }, - "node_modules/pkg-up/node_modules/p-try": { - "version": "2.2.0", + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "license": "MIT", "engines": { - "node": ">=6" + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, "node_modules/postcss": { - "version": "8.4.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.36.tgz", - "integrity": "sha512-/n7eumA6ZjFHAsbX30yhHup/IMkOmlmvtEi7P+6RMYf+bGJSUHc3geH4a0NSZxAz/RJfiS9tooCTs9LAVYUZKw==", + "version": "8.4.45", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", + "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", "funding": [ { "type": "opencollective", @@ -11357,17 +14265,20 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.1.0" + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/postcss-attribute-case-insensitive": { - "version": "5.0.1", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.10" @@ -11380,11 +14291,13 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2" } }, "node_modules/postcss-browser-comments": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", "license": "CC0-1.0", "engines": { "node": ">=8" @@ -11396,6 +14309,8 @@ }, "node_modules/postcss-calc": { "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.9", @@ -11407,6 +14322,8 @@ }, "node_modules/postcss-clamp": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -11419,7 +14336,9 @@ } }, "node_modules/postcss-color-functional-notation": { - "version": "4.2.3", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -11431,25 +14350,33 @@ "type": "opencollective", "url": "https://opencollective.com/csstools" }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, "peerDependencies": { "postcss": "^8.4" } }, - "node_modules/postcss-color-hex-alpha": { - "version": "8.0.3", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, "node_modules/postcss-color-rebeccapurple": { - "version": "7.0.2", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -11457,15 +14384,21 @@ "engines": { "node": "^12 || ^14 || >=16" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2" } }, "node_modules/postcss-colormin": { - "version": "5.3.0", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", "license": "MIT", "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "colord": "^2.9.1", "postcss-value-parser": "^4.2.0" @@ -11478,10 +14411,12 @@ } }, "node_modules/postcss-convert-values": { - "version": "5.1.2", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", "license": "MIT", "dependencies": { - "browserslist": "^4.20.3", + "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" }, "engines": { @@ -11493,6 +14428,8 @@ }, "node_modules/postcss-custom-media": { "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -11509,7 +14446,9 @@ } }, "node_modules/postcss-custom-properties": { - "version": "12.1.7", + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -11522,11 +14461,13 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, "node_modules/postcss-custom-selectors": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.4" @@ -11543,20 +14484,28 @@ } }, "node_modules/postcss-dir-pseudo-class": { - "version": "6.0.4", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", "license": "CC0-1.0", "dependencies": { - "postcss-selector-parser": "^6.0.9" + "postcss-selector-parser": "^6.0.10" }, "engines": { "node": "^12 || ^14 || >=16" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, "node_modules/postcss-discard-comments": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" @@ -11567,6 +14516,8 @@ }, "node_modules/postcss-discard-duplicates": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" @@ -11577,6 +14528,8 @@ }, "node_modules/postcss-discard-empty": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" @@ -11587,6 +14540,8 @@ }, "node_modules/postcss-discard-overridden": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" @@ -11596,121 +14551,9 @@ } }, "node_modules/postcss-double-position-gradients": { - "version": "3.1.1", - "license": "CC0-1.0", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-env-function": { - "version": "4.0.6", - "license": "CC0-1.0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-flexbugs-fixes": { - "version": "5.0.2", - "license": "MIT", - "peerDependencies": { - "postcss": "^8.1.4" - } - }, - "node_modules/postcss-focus-visible": { - "version": "6.0.4", - "license": "CC0-1.0", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-within": { - "version": "5.0.4", - "license": "CC0-1.0", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-font-variant": { - "version": "5.0.0", - "license": "MIT", - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-gap-properties": { - "version": "3.0.3", - "license": "CC0-1.0", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-image-set-function": { - "version": "4.0.6", - "license": "CC0-1.0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-initial": { - "version": "4.0.1", - "license": "MIT", - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, - "node_modules/postcss-lab-function": { - "version": "4.2.0", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", @@ -11723,24 +14566,195 @@ "type": "opencollective", "url": "https://opencollective.com/csstools" }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-env-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, "peerDependencies": { "postcss": "^8.4" } }, - "node_modules/postcss-load-config": { - "version": "3.1.4", + "node_modules/postcss-flexbugs-fixes": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", "license": "MIT", + "peerDependencies": { + "postcss": "^8.1.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "license": "CC0-1.0", "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" + "postcss-selector-parser": "^6.0.9" }, "engines": { - "node": ">= 10" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "license": "CC0-1.0", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", + "license": "CC0-1.0", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/postcss/" }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" @@ -11754,8 +14768,34 @@ } } }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/postcss-loader": { "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", "license": "MIT", "dependencies": { "cosmiconfig": "^7.0.0", @@ -11775,12 +14815,10 @@ } }, "node_modules/postcss-loader/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -11790,6 +14828,8 @@ }, "node_modules/postcss-logical": { "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" @@ -11800,6 +14840,8 @@ }, "node_modules/postcss-media-minmax": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -11809,11 +14851,13 @@ } }, "node_modules/postcss-merge-longhand": { - "version": "5.1.5", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.0" + "stylehacks": "^5.1.1" }, "engines": { "node": "^10 || ^12 || >=14.0" @@ -11823,10 +14867,12 @@ } }, "node_modules/postcss-merge-rules": { - "version": "5.1.2", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", "license": "MIT", "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "cssnano-utils": "^3.1.0", "postcss-selector-parser": "^6.0.5" @@ -11840,6 +14886,8 @@ }, "node_modules/postcss-minify-font-values": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -11853,6 +14901,8 @@ }, "node_modules/postcss-minify-gradients": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", "license": "MIT", "dependencies": { "colord": "^2.9.1", @@ -11867,10 +14917,12 @@ } }, "node_modules/postcss-minify-params": { - "version": "5.1.3", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", "license": "MIT", "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" }, @@ -11883,6 +14935,8 @@ }, "node_modules/postcss-minify-selectors": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.5" @@ -11895,7 +14949,9 @@ } }, "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" @@ -11905,7 +14961,9 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.0", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", @@ -11920,7 +14978,9 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.0.0", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", "license": "ISC", "dependencies": { "postcss-selector-parser": "^6.0.4" @@ -11934,6 +14994,8 @@ }, "node_modules/postcss-modules-values": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "license": "ISC", "dependencies": { "icss-utils": "^5.0.0" @@ -11946,24 +15008,34 @@ } }, "node_modules/postcss-nested": { - "version": "5.0.6", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.0.6" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } }, "node_modules/postcss-nesting": { - "version": "10.1.8", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", @@ -11977,11 +15049,13 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, "node_modules/postcss-normalize": { "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", "license": "CC0-1.0", "dependencies": { "@csstools/normalize.css": "*", @@ -11998,6 +15072,8 @@ }, "node_modules/postcss-normalize-charset": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" @@ -12008,6 +15084,8 @@ }, "node_modules/postcss-normalize-display-values": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -12020,7 +15098,9 @@ } }, "node_modules/postcss-normalize-positions": { - "version": "5.1.0", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -12033,7 +15113,9 @@ } }, "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.0", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -12047,6 +15129,8 @@ }, "node_modules/postcss-normalize-string": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -12060,6 +15144,8 @@ }, "node_modules/postcss-normalize-timing-functions": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -12072,10 +15158,12 @@ } }, "node_modules/postcss-normalize-unicode": { - "version": "5.1.0", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", "license": "MIT", "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" }, "engines": { @@ -12087,6 +15175,8 @@ }, "node_modules/postcss-normalize-url": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", "license": "MIT", "dependencies": { "normalize-url": "^6.0.1", @@ -12101,6 +15191,8 @@ }, "node_modules/postcss-normalize-whitespace": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -12113,7 +15205,9 @@ } }, "node_modules/postcss-opacity-percentage": { - "version": "1.1.2", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", "funding": [ { "type": "kofi", @@ -12127,10 +15221,15 @@ "license": "MIT", "engines": { "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-ordered-values": { - "version": "5.1.2", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", "license": "MIT", "dependencies": { "cssnano-utils": "^3.1.0", @@ -12144,24 +15243,9 @@ } }, "node_modules/postcss-overflow-shorthand": { - "version": "3.0.3", - "license": "CC0-1.0", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-page-break": { "version": "3.0.4", - "license": "MIT", - "peerDependencies": { - "postcss": "^8" - } - }, - "node_modules/postcss-place": { - "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -12169,75 +15253,113 @@ "engines": { "node": "^12 || ^14 || >=16" }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-preset-env": { - "version": "7.7.1", - "license": "CC0-1.0", - "dependencies": { - "@csstools/postcss-cascade-layers": "^1.0.2", - "@csstools/postcss-color-function": "^1.1.0", - "@csstools/postcss-font-format-keywords": "^1.0.0", - "@csstools/postcss-hwb-function": "^1.0.1", - "@csstools/postcss-ic-unit": "^1.0.0", - "@csstools/postcss-is-pseudo-class": "^2.0.4", - "@csstools/postcss-normalize-display-values": "^1.0.0", - "@csstools/postcss-oklab-function": "^1.1.0", - "@csstools/postcss-progressive-custom-properties": "^1.3.0", - "@csstools/postcss-stepped-value-functions": "^1.0.0", - "@csstools/postcss-trigonometric-functions": "^1.0.1", - "@csstools/postcss-unset-value": "^1.0.1", - "autoprefixer": "^10.4.7", - "browserslist": "^4.20.3", - "css-blank-pseudo": "^3.0.3", - "css-has-pseudo": "^3.0.4", - "css-prefers-color-scheme": "^6.0.3", - "cssdb": "^6.6.3", - "postcss-attribute-case-insensitive": "^5.0.1", - "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^4.2.3", - "postcss-color-hex-alpha": "^8.0.3", - "postcss-color-rebeccapurple": "^7.0.2", - "postcss-custom-media": "^8.0.1", - "postcss-custom-properties": "^12.1.7", - "postcss-custom-selectors": "^6.0.2", - "postcss-dir-pseudo-class": "^6.0.4", - "postcss-double-position-gradients": "^3.1.1", - "postcss-env-function": "^4.0.6", - "postcss-focus-visible": "^6.0.4", - "postcss-focus-within": "^5.0.4", - "postcss-font-variant": "^5.0.0", - "postcss-gap-properties": "^3.0.3", - "postcss-image-set-function": "^4.0.6", - "postcss-initial": "^4.0.1", - "postcss-lab-function": "^4.2.0", - "postcss-logical": "^5.0.4", - "postcss-media-minmax": "^5.0.0", - "postcss-nesting": "^10.1.7", - "postcss-opacity-percentage": "^1.1.2", - "postcss-overflow-shorthand": "^3.0.3", - "postcss-page-break": "^3.0.4", - "postcss-place": "^7.0.4", - "postcss-pseudo-class-any-link": "^7.1.4", - "postcss-replace-overflow-wrap": "^4.0.0", - "postcss-selector-not": "^6.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, "funding": { "type": "opencollective", "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "license": "CC0-1.0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-preset-env": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", + "license": "CC0-1.0", + "dependencies": { + "@csstools/postcss-cascade-layers": "^1.1.1", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.1.0", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.10", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-pseudo-class-any-link": { - "version": "7.1.4", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" @@ -12250,14 +15372,16 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.4" + "postcss": "^8.2" } }, "node_modules/postcss-reduce-initial": { - "version": "5.1.0", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", "license": "MIT", "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" }, "engines": { @@ -12269,6 +15393,8 @@ }, "node_modules/postcss-reduce-transforms": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -12282,13 +15408,17 @@ }, "node_modules/postcss-replace-overflow-wrap": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", "license": "MIT", "peerDependencies": { "postcss": "^8.0.3" } }, "node_modules/postcss-selector-not": { - "version": "6.0.0", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.10" @@ -12301,11 +15431,13 @@ "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.2" } }, "node_modules/postcss-selector-parser": { - "version": "6.0.10", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -12317,6 +15449,8 @@ }, "node_modules/postcss-svgo": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", @@ -12331,6 +15465,8 @@ }, "node_modules/postcss-svgo/node_modules/commander": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "license": "MIT", "engines": { "node": ">= 10" @@ -12338,6 +15474,8 @@ }, "node_modules/postcss-svgo/node_modules/css-tree": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "license": "MIT", "dependencies": { "mdn-data": "2.0.14", @@ -12349,10 +15487,23 @@ }, "node_modules/postcss-svgo/node_modules/mdn-data": { "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "license": "CC0-1.0" }, + "node_modules/postcss-svgo/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/postcss-svgo/node_modules/svgo": { "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", "license": "MIT", "dependencies": { "@trysound/sax": "0.2.0", @@ -12372,6 +15523,8 @@ }, "node_modules/postcss-unique-selectors": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.5" @@ -12385,10 +15538,14 @@ }, "node_modules/postcss-value-parser": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "license": "MIT", "engines": { "node": ">= 0.8.0" @@ -12396,6 +15553,8 @@ }, "node_modules/pretty-bytes": { "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "license": "MIT", "engines": { "node": ">=6" @@ -12406,6 +15565,8 @@ }, "node_modules/pretty-error": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", "license": "MIT", "dependencies": { "lodash": "^4.17.20", @@ -12414,6 +15575,8 @@ }, "node_modules/pretty-format": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", @@ -12426,6 +15589,8 @@ }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "license": "MIT", "engines": { "node": ">=10" @@ -12434,19 +15599,31 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "license": "MIT" + }, "node_modules/process-nextick-args": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, "node_modules/progress": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/promise": { - "version": "8.1.0", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", "license": "MIT", "dependencies": { "asap": "~2.0.6" @@ -12454,6 +15631,8 @@ }, "node_modules/prompts": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -12465,6 +15644,8 @@ }, "node_modules/prop-types": { "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -12474,10 +15655,14 @@ }, "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, "node_modules/proxy-addr": { "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -12489,17 +15674,23 @@ }, "node_modules/proxy-addr/node_modules/ipaddr.js": { "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/psl": { - "version": "1.8.0", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "license": "MIT" }, "node_modules/punycode": { - "version": "2.1.1", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "license": "MIT", "engines": { "node": ">=6" @@ -12507,6 +15698,9 @@ }, "node_modules/q": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)", "license": "MIT", "engines": { "node": ">=0.6.0", @@ -12517,6 +15711,7 @@ "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -12530,10 +15725,13 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "funding": [ { "type": "github", @@ -12550,18 +15748,10 @@ ], "license": "MIT" }, - "node_modules/quick-lru": { - "version": "5.1.1", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/raf": { "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", "license": "MIT", "dependencies": { "performance-now": "^2.1.0" @@ -12569,6 +15759,8 @@ }, "node_modules/randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" @@ -12576,6 +15768,8 @@ }, "node_modules/range-parser": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -12585,6 +15779,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -12599,6 +15794,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -12607,6 +15803,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -12616,6 +15813,8 @@ }, "node_modules/react": { "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -12627,6 +15826,8 @@ }, "node_modules/react-app-polyfill": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", "license": "MIT", "dependencies": { "core-js": "^3.19.2", @@ -12640,8 +15841,16 @@ "node": ">=14" } }, + "node_modules/react-app-polyfill/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, "node_modules/react-dev-utils": { "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.16.0", @@ -12675,6 +15884,8 @@ }, "node_modules/react-dev-utils/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -12688,6 +15899,8 @@ }, "node_modules/react-dev-utils/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -12702,6 +15915,8 @@ }, "node_modules/react-dev-utils/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -12712,20 +15927,14 @@ }, "node_modules/react-dev-utils/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, - "node_modules/react-dev-utils/node_modules/escape-string-regexp": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/react-dev-utils/node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -12740,21 +15949,26 @@ }, "node_modules/react-dev-utils/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "license": "MIT", "engines": { "node": ">= 12.13.0" } }, "node_modules/react-dev-utils/node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -12768,6 +15982,8 @@ }, "node_modules/react-dev-utils/node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -12781,6 +15997,8 @@ }, "node_modules/react-dev-utils/node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -12792,15 +16010,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/react-dev-utils/node_modules/path-exists": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/react-dev-utils/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -12811,6 +16024,8 @@ }, "node_modules/react-dom": { "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -12823,10 +16038,14 @@ }, "node_modules/react-error-overlay": { "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", "license": "MIT" }, "node_modules/react-intl": { "version": "5.25.1", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.25.1.tgz", + "integrity": "sha512-pkjdQDvpJROoXLMltkP/5mZb0/XqrqLoPGKUCfbdkP8m6U9xbK40K51Wu+a4aQqTEvEK5lHBk0fWzUV72SJ3Hg==", "license": "BSD-3-Clause", "dependencies": { "@formatjs/ecma402-abstract": "1.11.4", @@ -12851,11 +16070,15 @@ } }, "node_modules/react-is": { - "version": "17.0.2", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "license": "MIT" }, "node_modules/react-refresh": { "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12863,6 +16086,8 @@ }, "node_modules/react-scripts": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", @@ -12933,13 +16158,15 @@ } }, "node_modules/react-scripts/node_modules/@eslint/eslintrc": { - "version": "1.3.0", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -12948,22 +16175,37 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/react-scripts/node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/react-scripts/node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "license": "BSD-3-Clause" + }, "node_modules/react-scripts/node_modules/acorn": { - "version": "8.7.1", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -12974,6 +16216,8 @@ }, "node_modules/react-scripts/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -12987,10 +16231,14 @@ }, "node_modules/react-scripts/node_modules/argparse": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, "node_modules/react-scripts/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -13005,6 +16253,8 @@ }, "node_modules/react-scripts/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -13015,57 +16265,54 @@ }, "node_modules/react-scripts/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, - "node_modules/react-scripts/node_modules/escape-string-regexp": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/react-scripts/node_modules/eslint": { - "version": "8.17.0", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "license": "MIT", "dependencies": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -13079,6 +16326,8 @@ }, "node_modules/react-scripts/node_modules/eslint-config-react-app": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", @@ -13105,6 +16354,8 @@ }, "node_modules/react-scripts/node_modules/eslint-plugin-flowtype": { "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", "license": "BSD-3-Clause", "dependencies": { "lodash": "^4.17.21", @@ -13120,7 +16371,9 @@ } }, "node_modules/react-scripts/node_modules/eslint-scope": { - "version": "7.1.1", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -13128,52 +16381,60 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/react-scripts/node_modules/eslint-utils": { - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "url": "https://opencollective.com/eslint" } }, - "node_modules/react-scripts/node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.3.0", + "node_modules/react-scripts/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/react-scripts/node_modules/espree": { - "version": "9.3.2", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.7.1", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/react-scripts/node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "license": "Apache-2.0", + "node_modules/react-scripts/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/react-scripts/node_modules/glob-parent": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -13183,7 +16444,9 @@ } }, "node_modules/react-scripts/node_modules/globals": { - "version": "13.15.0", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -13197,13 +16460,17 @@ }, "node_modules/react-scripts/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/react-scripts/node_modules/ignore": { - "version": "5.2.0", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -13211,6 +16478,8 @@ }, "node_modules/react-scripts/node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -13219,13 +16488,56 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/react-scripts/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/react-scripts/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" + "p-locate": "^5.0.0" }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-scripts/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-scripts/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-scripts/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -13235,6 +16547,8 @@ }, "node_modules/react-scripts/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13245,6 +16559,8 @@ }, "node_modules/react-scripts/node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -13255,6 +16571,8 @@ }, "node_modules/react-transition-group": { "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "license": "BSD-3-Clause", "dependencies": { "@babel/runtime": "^7.5.5", @@ -13267,8 +16585,19 @@ "react-dom": ">=16.6.0" } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, "node_modules/readable-stream": { - "version": "3.6.0", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -13281,6 +16610,8 @@ }, "node_modules/readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "license": "MIT", "dependencies": { "picomatch": "^2.2.1" @@ -13291,6 +16622,8 @@ }, "node_modules/recursive-readdir": { "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", "license": "MIT", "dependencies": { "minimatch": "^3.0.5" @@ -13299,12 +16632,37 @@ "node": ">=6.0.0" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerate": { "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.0.1", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "license": "MIT", "dependencies": { "regenerate": "^1.4.2" @@ -13314,27 +16672,36 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.10", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "license": "MIT" }, "node_modules/regenerator-transform": { - "version": "0.15.0", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regex-parser": { - "version": "2.2.11", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", + "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", "license": "MIT" }, "node_modules/regexp.prototype.flags": { - "version": "1.4.3", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -13345,6 +16712,8 @@ }, "node_modules/regexpp": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "license": "MIT", "engines": { "node": ">=8" @@ -13354,26 +16723,26 @@ } }, "node_modules/regexpu-core": { - "version": "5.0.1", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "license": "MIT", "dependencies": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.0.1", - "regjsgen": "^0.6.0", - "regjsparser": "^0.8.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" }, "engines": { "node": ">=4" } }, - "node_modules/regjsgen": { - "version": "0.6.0", - "license": "MIT" - }, "node_modules/regjsparser": { - "version": "0.8.4", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "license": "BSD-2-Clause", "dependencies": { "jsesc": "~0.5.0" @@ -13384,12 +16753,16 @@ }, "node_modules/regjsparser/node_modules/jsesc": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "bin": { "jsesc": "bin/jsesc" } }, "node_modules/relateurl": { "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -13397,6 +16770,8 @@ }, "node_modules/renderkid": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", "license": "MIT", "dependencies": { "css-select": "^4.1.3", @@ -13408,6 +16783,8 @@ }, "node_modules/require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -13415,6 +16792,8 @@ }, "node_modules/require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -13422,17 +16801,23 @@ }, "node_modules/requires-port": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "license": "MIT" }, "node_modules/reselect": { - "version": "4.1.7", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==", "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.0", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "license": "MIT", "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -13445,6 +16830,8 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" @@ -13455,6 +16842,8 @@ }, "node_modules/resolve-cwd/node_modules/resolve-from": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "license": "MIT", "engines": { "node": ">=8" @@ -13462,6 +16851,8 @@ }, "node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "license": "MIT", "engines": { "node": ">=4" @@ -13469,6 +16860,8 @@ }, "node_modules/resolve-url-loader": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", "license": "MIT", "dependencies": { "adjust-sourcemap-loader": "^4.0.0", @@ -13493,12 +16886,22 @@ } } }, + "node_modules/resolve-url-loader/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, "node_modules/resolve-url-loader/node_modules/picocolors": { "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", "license": "ISC" }, "node_modules/resolve-url-loader/node_modules/postcss": { "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", "license": "MIT", "dependencies": { "picocolors": "^0.2.1", @@ -13512,8 +16915,19 @@ "url": "https://opencollective.com/postcss/" } }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve.exports": { - "version": "1.1.0", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", "license": "MIT", "engines": { "node": ">=10" @@ -13521,6 +16935,8 @@ }, "node_modules/retry": { "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "license": "MIT", "engines": { "node": ">= 4" @@ -13528,6 +16944,8 @@ }, "node_modules/reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -13536,6 +16954,9 @@ }, "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -13548,7 +16969,9 @@ } }, "node_modules/rollup": { - "version": "2.75.6", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "license": "MIT", "bin": { "rollup": "dist/bin/rollup" @@ -13562,6 +16985,9 @@ }, "node_modules/rollup-plugin-terser": { "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.10.4", @@ -13575,6 +17001,8 @@ }, "node_modules/rollup-plugin-terser/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -13582,6 +17010,8 @@ }, "node_modules/rollup-plugin-terser/node_modules/jest-worker": { "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -13594,6 +17024,8 @@ }, "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" @@ -13601,6 +17033,8 @@ }, "node_modules/rollup-plugin-terser/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -13611,6 +17045,8 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "funding": [ { "type": "github", @@ -13630,20 +17066,77 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { - "version": "5.1.2", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT" }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "node_modules/sanitize.css": { "version": "13.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==", "license": "CC0-1.0" }, "node_modules/sass-loader": { "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", "license": "MIT", "dependencies": { "klona": "^2.0.4", @@ -13680,10 +17173,14 @@ }, "node_modules/sax": { "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "license": "ISC" }, "node_modules/saxes": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" @@ -13694,6 +17191,8 @@ }, "node_modules/scheduler": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -13701,30 +17200,71 @@ } }, "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" } }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, "node_modules/select-hose": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", "license": "MIT" }, "node_modules/selfsigned": { - "version": "2.0.1", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "license": "MIT", "dependencies": { + "@types/node-forge": "^1.3.0", "node-forge": "^1" }, "engines": { @@ -13735,12 +17275,15 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/send": { "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -13763,6 +17306,8 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -13770,22 +17315,29 @@ }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/serve-index": { "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "license": "MIT", "dependencies": { "accepts": "~1.3.4", @@ -13802,6 +17354,8 @@ }, "node_modules/serve-index/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -13809,6 +17363,8 @@ }, "node_modules/serve-index/node_modules/depd": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -13816,6 +17372,8 @@ }, "node_modules/serve-index/node_modules/http-errors": { "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "license": "MIT", "dependencies": { "depd": "~1.1.2", @@ -13829,18 +17387,26 @@ }, "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", "license": "ISC" }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "license": "ISC" }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -13848,6 +17414,8 @@ }, "node_modules/serve-static": { "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", @@ -13859,12 +17427,48 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -13875,22 +17479,35 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { - "version": "1.7.3", - "license": "MIT" + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/side-channel": { - "version": "1.0.4", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -13898,14 +17515,20 @@ }, "node_modules/signal-exit": { "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, "node_modules/sisteransi": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "license": "MIT", "engines": { "node": ">=8" @@ -13913,6 +17536,8 @@ }, "node_modules/slice-ansi": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -13928,6 +17553,8 @@ }, "node_modules/slice-ansi/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -13941,6 +17568,8 @@ }, "node_modules/slice-ansi/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -13951,10 +17580,14 @@ }, "node_modules/slice-ansi/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/sockjs": { "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "license": "MIT", "dependencies": { "faye-websocket": "^0.11.3", @@ -13964,10 +17597,14 @@ }, "node_modules/source-list-map": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", "license": "MIT" }, "node_modules/source-map": { - "version": "0.6.1", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -13977,12 +17614,15 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-loader": { - "version": "3.0.1", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", + "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", "license": "MIT", "dependencies": { "abab": "^2.0.5", @@ -14002,18 +17642,34 @@ }, "node_modules/source-map-support": { "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sourcemap-codec": { "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", "license": "MIT" }, "node_modules/spdy": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "license": "MIT", "dependencies": { "debug": "^4.1.0", @@ -14028,6 +17684,8 @@ }, "node_modules/spdy-transport": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "license": "MIT", "dependencies": { "debug": "^4.1.0", @@ -14040,14 +17698,21 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "license": "BSD-3-Clause" }, "node_modules/stable": { "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", "license": "MIT" }, "node_modules/stack-utils": { - "version": "2.0.5", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" @@ -14058,6 +17723,8 @@ }, "node_modules/stack-utils/node_modules/escape-string-regexp": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "license": "MIT", "engines": { "node": ">=8" @@ -14065,42 +17732,144 @@ }, "node_modules/stackframe": { "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", "license": "MIT" }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "license": "MIT", + "dependencies": { + "escodegen": "^1.8.1" + } + }, + "node_modules/static-eval/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/static-eval/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/static-eval/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-eval/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/statuses": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "license": "MIT", + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/string_decoder": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/string-length": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "license": "MIT", "dependencies": { "char-regex": "^1.0.2", @@ -14112,10 +17881,14 @@ }, "node_modules/string-natural-compare": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", "license": "MIT" }, "node_modules/string-width": { "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -14126,46 +17899,123 @@ "node": ">=8" } }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "license": "MIT" - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.7", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string.prototype.includes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", + "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.1", - "side-channel": "^1.0.4" + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimend": { - "version": "1.0.5", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.5", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -14173,6 +18023,8 @@ }, "node_modules/stringify-object": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", "license": "BSD-2-Clause", "dependencies": { "get-own-enumerable-property-symbols": "^3.0.0", @@ -14185,6 +18037,21 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -14195,6 +18062,8 @@ }, "node_modules/strip-bom": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "license": "MIT", "engines": { "node": ">=8" @@ -14202,6 +18071,8 @@ }, "node_modules/strip-comments": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", "license": "MIT", "engines": { "node": ">=10" @@ -14209,6 +18080,8 @@ }, "node_modules/strip-final-newline": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "license": "MIT", "engines": { "node": ">=6" @@ -14216,6 +18089,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "license": "MIT", "engines": { "node": ">=8" @@ -14225,7 +18100,9 @@ } }, "node_modules/style-loader": { - "version": "3.3.1", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", "license": "MIT", "engines": { "node": ">= 12.13.0" @@ -14239,10 +18116,12 @@ } }, "node_modules/stylehacks": { - "version": "5.1.0", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", "license": "MIT", "dependencies": { - "browserslist": "^4.16.6", + "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" }, "engines": { @@ -14253,11 +18132,90 @@ } }, "node_modules/stylis": { - "version": "4.1.3", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", "license": "MIT" }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "license": "MIT", "dependencies": { "has-flag": "^3.0.0" @@ -14267,7 +18225,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "2.2.0", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0", @@ -14279,6 +18239,8 @@ }, "node_modules/supports-hyperlinks/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -14286,6 +18248,8 @@ }, "node_modules/supports-hyperlinks/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14296,6 +18260,8 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -14306,10 +18272,15 @@ }, "node_modules/svg-parser": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", "license": "MIT" }, "node_modules/svgo": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", "license": "MIT", "dependencies": { "chalk": "^2.4.1", @@ -14335,6 +18306,8 @@ }, "node_modules/svgo/node_modules/css-select": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -14345,6 +18318,8 @@ }, "node_modules/svgo/node_modules/css-what": { "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", "license": "BSD-2-Clause", "engines": { "node": ">= 6" @@ -14355,6 +18330,8 @@ }, "node_modules/svgo/node_modules/dom-serializer": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", @@ -14363,6 +18340,8 @@ }, "node_modules/svgo/node_modules/domutils": { "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "0", @@ -14371,10 +18350,14 @@ }, "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "license": "BSD-2-Clause" }, "node_modules/svgo/node_modules/nth-check": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "~1.0.0" @@ -14382,10 +18365,14 @@ }, "node_modules/symbol-tree": { "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "license": "MIT" }, "node_modules/table": { - "version": "6.8.0", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "license": "BSD-3-Clause", "dependencies": { "ajv": "^8.0.1", @@ -14399,13 +18386,15 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.11.0", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -14414,51 +18403,51 @@ }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/tailwindcss": { - "version": "3.0.24", + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", + "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==", "license": "MIT", "dependencies": { - "arg": "^5.0.1", + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", "chokidar": "^3.5.3", - "color-name": "^1.1.4", - "detective": "^5.2.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.2.11", + "fast-glob": "^3.3.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "lilconfig": "^2.0.5", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.12", - "postcss-js": "^4.0.0", - "postcss-load-config": "^3.1.4", - "postcss-nested": "5.0.6", - "postcss-selector-parser": "^6.0.10", - "postcss-value-parser": "^4.2.0", - "quick-lru": "^5.1.1", - "resolve": "^1.22.0" + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" }, "engines": { - "node": ">=12.13.0" - }, - "peerDependencies": { - "postcss": "^8.0.9" + "node": ">=14.0.0" } }, - "node_modules/tailwindcss/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, "node_modules/tailwindcss/node_modules/glob-parent": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -14469,6 +18458,8 @@ }, "node_modules/tapable": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "license": "MIT", "engines": { "node": ">=6" @@ -14476,6 +18467,8 @@ }, "node_modules/temp-dir": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", "license": "MIT", "engines": { "node": ">=8" @@ -14483,6 +18476,8 @@ }, "node_modules/tempy": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", "license": "MIT", "dependencies": { "is-stream": "^2.0.0", @@ -14499,6 +18494,8 @@ }, "node_modules/tempy/node_modules/type-fest": { "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -14509,6 +18506,8 @@ }, "node_modules/terminal-link": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", @@ -14522,9 +18521,10 @@ } }, "node_modules/terser": { - "version": "5.30.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", - "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -14542,6 +18542,7 @@ "version": "5.3.10", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -14571,10 +18572,29 @@ } } }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/terser/node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -14584,10 +18604,14 @@ }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "license": "MIT" }, "node_modules/test-exclude": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", @@ -14600,22 +18624,53 @@ }, "node_modules/text-table": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "license": "MIT" }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/throat": { - "version": "6.0.1", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", "license": "MIT" }, "node_modules/thunky": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "license": "MIT" }, "node_modules/tmpl": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "license": "MIT", "engines": { "node": ">=4" @@ -14623,6 +18678,8 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -14633,15 +18690,18 @@ }, "node_modules/toidentifier": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -14656,12 +18716,15 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "license": "MIT", "engines": { "node": ">= 4.0.0" } }, "node_modules/tr46": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "license": "MIT", "dependencies": { "punycode": "^2.1.1" @@ -14672,14 +18735,24 @@ }, "node_modules/tryer": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", "license": "MIT" }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, "node_modules/tsconfig-paths": { - "version": "3.14.1", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } @@ -14688,6 +18761,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -14697,17 +18771,23 @@ }, "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/tslib": { - "version": "2.4.0", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "license": "MIT", "dependencies": { "tslib": "^1.8.1" @@ -14721,10 +18801,14 @@ }, "node_modules/tsutils/node_modules/tslib": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" @@ -14735,6 +18819,8 @@ }, "node_modules/type-detect": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "license": "MIT", "engines": { "node": ">=4" @@ -14742,6 +18828,8 @@ }, "node_modules/type-fest": { "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -14754,6 +18842,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -14762,15 +18851,92 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "license": "MIT", "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/typescript": { - "version": "4.7.3", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "license": "Apache-2.0", "peer": true, "bin": { @@ -14778,11 +18944,13 @@ "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "license": "MIT", "dependencies": { "call-bind": "^1.0.2", @@ -14794,8 +18962,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "license": "MIT", "engines": { "node": ">=4" @@ -14803,6 +18985,8 @@ }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", @@ -14813,14 +18997,18 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.0.0", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.0.0", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "license": "MIT", "engines": { "node": ">=4" @@ -14828,6 +19016,8 @@ }, "node_modules/unique-string": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "license": "MIT", "dependencies": { "crypto-random-string": "^2.0.0" @@ -14837,7 +19027,9 @@ } }, "node_modules/universalify": { - "version": "2.0.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -14845,6 +19037,8 @@ }, "node_modules/unpipe": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -14852,10 +19046,14 @@ }, "node_modules/unquote": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", "license": "MIT" }, "node_modules/upath": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "license": "MIT", "engines": { "node": ">=4", @@ -14863,9 +19061,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "funding": [ { "type": "opencollective", @@ -14880,9 +19078,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -14893,6 +19092,8 @@ }, "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -14902,6 +19103,7 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -14909,10 +19111,14 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/util.promisify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", "license": "MIT", "dependencies": { "define-properties": "^1.1.3", @@ -14926,10 +19132,14 @@ }, "node_modules/utila": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "license": "MIT", "engines": { "node": ">= 0.4.0" @@ -14937,17 +19147,23 @@ }, "node_modules/uuid": { "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache": { - "version": "2.3.0", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", "license": "MIT" }, "node_modules/v8-to-istanbul": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "license": "ISC", "dependencies": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -14958,8 +19174,16 @@ "node": ">=10.12.0" } }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, "node_modules/v8-to-istanbul/node_modules/source-map": { "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "license": "BSD-3-Clause", "engines": { "node": ">= 8" @@ -14967,6 +19191,8 @@ }, "node_modules/vary": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -14974,6 +19200,9 @@ }, "node_modules/w3c-hr-time": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", "license": "MIT", "dependencies": { "browser-process-hrtime": "^1.0.0" @@ -14981,6 +19210,8 @@ }, "node_modules/w3c-xmlserializer": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", "license": "MIT", "dependencies": { "xml-name-validator": "^3.0.0" @@ -14991,15 +19222,18 @@ }, "node_modules/walker": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } }, "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -15010,6 +19244,8 @@ }, "node_modules/wbuf": { "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" @@ -15017,26 +19253,28 @@ }, "node_modules/webidl-conversions": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", "license": "BSD-2-Clause", "engines": { "node": ">=10.4" } }, "node_modules/webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -15072,6 +19310,7 @@ "version": "5.3.4", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -15090,53 +19329,10 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.11.0", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/webpack-dev-server": { - "version": "4.9.2", + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.9", @@ -15145,29 +19341,30 @@ "@types/serve-index": "^1.9.1", "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", + "@types/ws": "^8.5.5", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.0.11", "chokidar": "^3.5.3", "colorette": "^2.0.10", "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", + "connect-history-api-fallback": "^2.0.0", "default-gateway": "^6.0.3", "express": "^4.17.3", "graceful-fs": "^4.2.6", "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.3", "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", "open": "^8.0.9", "p-retry": "^4.5.0", "rimraf": "^3.0.2", "schema-utils": "^4.0.0", - "selfsigned": "^2.0.1", + "selfsigned": "^2.1.1", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" @@ -15175,69 +19372,33 @@ "engines": { "node": ">= 12.13.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, "peerDependencies": { "webpack": "^4.37.0 || ^5.0.0" }, "peerDependenciesMeta": { + "webpack": { + "optional": true + }, "webpack-cli": { "optional": true } } }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.11.0", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.7.0", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -15250,6 +19411,8 @@ }, "node_modules/webpack-manifest-plugin": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", "license": "MIT", "dependencies": { "tapable": "^2.0.0", @@ -15262,8 +19425,19 @@ "webpack": "^4.44.2 || ^5.47.0" } }, + "node_modules/webpack-manifest-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", "license": "MIT", "dependencies": { "source-list-map": "^2.0.1", @@ -15275,15 +19449,18 @@ }, "node_modules/webpack-sources": { "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -15291,16 +19468,37 @@ "node": ">=0.4.0" } }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/webpack/node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", "peerDependencies": { "acorn": "^8" } }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/websocket-driver": { "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", @@ -15313,6 +19511,8 @@ }, "node_modules/websocket-extensions": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "license": "Apache-2.0", "engines": { "node": ">=0.8.0" @@ -15320,6 +19520,8 @@ }, "node_modules/whatwg-encoding": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", "license": "MIT", "dependencies": { "iconv-lite": "0.4.24" @@ -15327,6 +19529,8 @@ }, "node_modules/whatwg-encoding/node_modules/iconv-lite": { "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -15336,15 +19540,21 @@ } }, "node_modules/whatwg-fetch": { - "version": "3.6.2", + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", "license": "MIT" }, "node_modules/whatwg-mimetype": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", "license": "MIT" }, "node_modules/whatwg-url": { "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "license": "MIT", "dependencies": { "lodash": "^4.7.0", @@ -15357,6 +19567,8 @@ }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -15370,6 +19582,8 @@ }, "node_modules/which-boxed-primitive": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", @@ -15382,31 +19596,101 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-builtin-type": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "license": "MIT", + "dependencies": { + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/workbox-background-sync": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", "license": "MIT", "dependencies": { - "idb": "^6.1.4", - "workbox-core": "6.5.3" + "idb": "^7.0.1", + "workbox-core": "6.6.0" } }, "node_modules/workbox-broadcast-update": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", "license": "MIT", "dependencies": { - "workbox-core": "6.5.3" + "workbox-core": "6.6.0" } }, "node_modules/workbox-build": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", "license": "MIT", "dependencies": { "@apideck/better-ajv-errors": "^0.3.1", @@ -15431,28 +19715,30 @@ "strip-comments": "^2.0.1", "tempy": "^0.6.0", "upath": "^1.2.0", - "workbox-background-sync": "6.5.3", - "workbox-broadcast-update": "6.5.3", - "workbox-cacheable-response": "6.5.3", - "workbox-core": "6.5.3", - "workbox-expiration": "6.5.3", - "workbox-google-analytics": "6.5.3", - "workbox-navigation-preload": "6.5.3", - "workbox-precaching": "6.5.3", - "workbox-range-requests": "6.5.3", - "workbox-recipes": "6.5.3", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3", - "workbox-streams": "6.5.3", - "workbox-sw": "6.5.3", - "workbox-window": "6.5.3" + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" }, "engines": { "node": ">=10.0.0" } }, "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { - "version": "0.3.4", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", "license": "MIT", "dependencies": { "json-schema": "^0.4.0", @@ -15467,13 +19753,15 @@ } }, "node_modules/workbox-build/node_modules/ajv": { - "version": "8.11.0", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -15482,6 +19770,8 @@ }, "node_modules/workbox-build/node_modules/fs-extra": { "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", @@ -15495,10 +19785,14 @@ }, "node_modules/workbox-build/node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/workbox-build/node_modules/source-map": { "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", "license": "BSD-3-Clause", "dependencies": { "whatwg-url": "^7.0.0" @@ -15509,6 +19803,8 @@ }, "node_modules/workbox-build/node_modules/tr46": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", "license": "MIT", "dependencies": { "punycode": "^2.1.0" @@ -15516,10 +19812,14 @@ }, "node_modules/workbox-build/node_modules/webidl-conversions": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "license": "BSD-2-Clause" }, "node_modules/workbox-build/node_modules/whatwg-url": { "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "license": "MIT", "dependencies": { "lodash.sortby": "^4.7.0", @@ -15528,104 +19828,132 @@ } }, "node_modules/workbox-cacheable-response": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", "license": "MIT", "dependencies": { - "workbox-core": "6.5.3" + "workbox-core": "6.6.0" } }, "node_modules/workbox-core": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==", "license": "MIT" }, "node_modules/workbox-expiration": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", "license": "MIT", "dependencies": { - "idb": "^6.1.4", - "workbox-core": "6.5.3" + "idb": "^7.0.1", + "workbox-core": "6.6.0" } }, "node_modules/workbox-google-analytics": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", "license": "MIT", "dependencies": { - "workbox-background-sync": "6.5.3", - "workbox-core": "6.5.3", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3" + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" } }, "node_modules/workbox-navigation-preload": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", "license": "MIT", "dependencies": { - "workbox-core": "6.5.3" + "workbox-core": "6.6.0" } }, "node_modules/workbox-precaching": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", "license": "MIT", "dependencies": { - "workbox-core": "6.5.3", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3" + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" } }, "node_modules/workbox-range-requests": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", "license": "MIT", "dependencies": { - "workbox-core": "6.5.3" + "workbox-core": "6.6.0" } }, "node_modules/workbox-recipes": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", "license": "MIT", "dependencies": { - "workbox-cacheable-response": "6.5.3", - "workbox-core": "6.5.3", - "workbox-expiration": "6.5.3", - "workbox-precaching": "6.5.3", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3" + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" } }, "node_modules/workbox-routing": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", "license": "MIT", "dependencies": { - "workbox-core": "6.5.3" + "workbox-core": "6.6.0" } }, "node_modules/workbox-strategies": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", "license": "MIT", "dependencies": { - "workbox-core": "6.5.3" + "workbox-core": "6.6.0" } }, "node_modules/workbox-streams": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", "license": "MIT", "dependencies": { - "workbox-core": "6.5.3", - "workbox-routing": "6.5.3" + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" } }, "node_modules/workbox-sw": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==", "license": "MIT" }, "node_modules/workbox-webpack-plugin": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", "license": "MIT", "dependencies": { "fast-json-stable-stringify": "^2.1.0", "pretty-bytes": "^5.4.1", "upath": "^1.2.0", "webpack-sources": "^1.4.3", - "workbox-build": "6.5.3" + "workbox-build": "6.6.0" }, "engines": { "node": ">=10.0.0" @@ -15634,8 +19962,19 @@ "webpack": "^4.4.0 || ^5.9.0" } }, + "node_modules/workbox-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", "license": "MIT", "dependencies": { "source-list-map": "^2.0.0", @@ -15643,15 +19982,19 @@ } }, "node_modules/workbox-window": { - "version": "6.5.3", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", "license": "MIT", "dependencies": { "@types/trusted-types": "^2.0.2", - "workbox-core": "6.5.3" + "workbox-core": "6.6.0" } }, "node_modules/wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -15665,8 +20008,61 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -15680,6 +20076,8 @@ }, "node_modules/wrap-ansi/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -15690,14 +20088,20 @@ }, "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/wrappy": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/write-file-atomic": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -15707,7 +20111,9 @@ } }, "node_modules/ws": { - "version": "7.5.8", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "license": "MIT", "engines": { "node": ">=8.3.0" @@ -15727,32 +20133,35 @@ }, "node_modules/xml-name-validator": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "license": "Apache-2.0" }, "node_modules/xmlchars": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "license": "MIT" }, - "node_modules/xtend": { - "version": "4.0.2", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { - "version": "4.0.0", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "license": "ISC", "engines": { "node": ">= 6" @@ -15760,6 +20169,8 @@ }, "node_modules/yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "license": "MIT", "dependencies": { "cliui": "^7.0.2", @@ -15776,6 +20187,8 @@ }, "node_modules/yargs-parser": { "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "license": "ISC", "engines": { "node": ">=10" @@ -15783,6 +20196,8 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "license": "MIT", "engines": { "node": ">=10" @@ -15791,9411 +20206,5 @@ "url": "https://github.com/sponsors/sindresorhus" } } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", - "requires": { - "@babel/highlight": "^7.24.2", - "picocolors": "^1.0.0" - } - }, - "@babel/compat-data": { - "version": "7.17.10" - }, - "@babel/core": { - "version": "7.18.2", - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-compilation-targets": "^7.18.2", - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.0", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - } - }, - "@babel/eslint-parser": { - "version": "7.18.2", - "requires": { - "eslint-scope": "^5.1.1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" - } - }, - "@babel/generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", - "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", - "requires": { - "@babel/types": "^7.24.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.7", - "requires": { - "@babel/helper-explode-assignable-expression": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.18.2", - "requires": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.20.2", - "semver": "^6.3.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.18.0", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-member-expression-to-functions": "^7.17.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.17.12", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "regexpu-core": "^5.0.1" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.1", - "requires": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.16.7", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.17.7", - "requires": { - "@babel/types": "^7.17.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-module-transforms": { - "version": "7.18.0", - "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.16.7", - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.17.12" - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.16.8", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-wrap-function": "^7.16.8", - "@babel/types": "^7.16.8" - } - }, - "@babel/helper-replace-supers": { - "version": "7.18.2", - "requires": { - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-member-expression-to-functions": "^7.17.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2" - } - }, - "@babel/helper-simple-access": { - "version": "7.18.2", - "requires": { - "@babel/types": "^7.18.2" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==" - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" - }, - "@babel/helper-validator-option": { - "version": "7.16.7" - }, - "@babel/helper-wrap-function": { - "version": "7.16.8", - "requires": { - "@babel/helper-function-name": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.8", - "@babel/types": "^7.16.8" - } - }, - "@babel/helpers": { - "version": "7.18.2", - "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2" - } - }, - "@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - } - }, - "@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==" - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.17.12" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-remap-async-to-generator": "^7.16.8", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.17.12", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.18.0", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-decorators": { - "version": "7.18.2", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-replace-supers": "^7.18.2", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/plugin-syntax-decorators": "^7.17.12", - "charcodes": "^0.2.0" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.0", - "requires": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-compilation-targets": "^7.17.10", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.17.12" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.17.12", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.17.12", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-create-class-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.17.12", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-decorators": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-flow": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-syntax-import-assertions": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.17.12", - "requires": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-remap-async-to-generator": "^7.16.8" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.18.4", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.18.4", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-replace-supers": "^7.18.2", - "@babel/helper-split-export-declaration": "^7.16.7", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.18.0", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.16.7", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.7", - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-flow": "^7.17.12" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.18.1", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.16.7", - "requires": { - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.18.0", - "requires": { - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.18.2", - "requires": { - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-simple-access": "^7.18.2", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.18.4", - "requires": { - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-validator-identifier": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.18.0", - "requires": { - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.17.12", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.17.12", - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-react-constant-elements": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.17.12", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-jsx": "^7.17.12", - "@babel/types": "^7.17.12" - } - }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.16.7", - "requires": { - "@babel/plugin-transform-react-jsx": "^7.16.7" - } - }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.0", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.18.0", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "regenerator-transform": "^0.15.0" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.18.2", - "requires": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.17.12", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.5.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "semver": "^6.3.0" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.18.2", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.18.4", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.0", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/plugin-syntax-typescript": "^7.17.12" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.16.7", - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.16.7", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/preset-env": { - "version": "7.18.2", - "requires": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-compilation-targets": "^7.18.2", - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.17.12", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.17.12", - "@babel/plugin-proposal-async-generator-functions": "^7.17.12", - "@babel/plugin-proposal-class-properties": "^7.17.12", - "@babel/plugin-proposal-class-static-block": "^7.18.0", - "@babel/plugin-proposal-dynamic-import": "^7.16.7", - "@babel/plugin-proposal-export-namespace-from": "^7.17.12", - "@babel/plugin-proposal-json-strings": "^7.17.12", - "@babel/plugin-proposal-logical-assignment-operators": "^7.17.12", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.17.12", - "@babel/plugin-proposal-numeric-separator": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.18.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", - "@babel/plugin-proposal-optional-chaining": "^7.17.12", - "@babel/plugin-proposal-private-methods": "^7.17.12", - "@babel/plugin-proposal-private-property-in-object": "^7.17.12", - "@babel/plugin-proposal-unicode-property-regex": "^7.17.12", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.17.12", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.17.12", - "@babel/plugin-transform-async-to-generator": "^7.17.12", - "@babel/plugin-transform-block-scoped-functions": "^7.16.7", - "@babel/plugin-transform-block-scoping": "^7.17.12", - "@babel/plugin-transform-classes": "^7.17.12", - "@babel/plugin-transform-computed-properties": "^7.17.12", - "@babel/plugin-transform-destructuring": "^7.18.0", - "@babel/plugin-transform-dotall-regex": "^7.16.7", - "@babel/plugin-transform-duplicate-keys": "^7.17.12", - "@babel/plugin-transform-exponentiation-operator": "^7.16.7", - "@babel/plugin-transform-for-of": "^7.18.1", - "@babel/plugin-transform-function-name": "^7.16.7", - "@babel/plugin-transform-literals": "^7.17.12", - "@babel/plugin-transform-member-expression-literals": "^7.16.7", - "@babel/plugin-transform-modules-amd": "^7.18.0", - "@babel/plugin-transform-modules-commonjs": "^7.18.2", - "@babel/plugin-transform-modules-systemjs": "^7.18.0", - "@babel/plugin-transform-modules-umd": "^7.18.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.17.12", - "@babel/plugin-transform-new-target": "^7.17.12", - "@babel/plugin-transform-object-super": "^7.16.7", - "@babel/plugin-transform-parameters": "^7.17.12", - "@babel/plugin-transform-property-literals": "^7.16.7", - "@babel/plugin-transform-regenerator": "^7.18.0", - "@babel/plugin-transform-reserved-words": "^7.17.12", - "@babel/plugin-transform-shorthand-properties": "^7.16.7", - "@babel/plugin-transform-spread": "^7.17.12", - "@babel/plugin-transform-sticky-regex": "^7.16.7", - "@babel/plugin-transform-template-literals": "^7.18.2", - "@babel/plugin-transform-typeof-symbol": "^7.17.12", - "@babel/plugin-transform-unicode-escapes": "^7.16.7", - "@babel/plugin-transform-unicode-regex": "^7.16.7", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.18.2", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.5.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.22.1", - "semver": "^6.3.0" - } - }, - "@babel/preset-modules": { - "version": "0.1.5", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/preset-react": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-react-display-name": "^7.16.7", - "@babel/plugin-transform-react-jsx": "^7.17.12", - "@babel/plugin-transform-react-jsx-development": "^7.16.7", - "@babel/plugin-transform-react-pure-annotations": "^7.16.7" - } - }, - "@babel/preset-typescript": { - "version": "7.17.12", - "requires": { - "@babel/helper-plugin-utils": "^7.17.12", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-typescript": "^7.17.12" - } - }, - "@babel/runtime": { - "version": "7.20.1", - "requires": { - "regenerator-runtime": "^0.13.10" - } - }, - "@babel/runtime-corejs3": { - "version": "7.18.3", - "requires": { - "core-js-pure": "^3.20.2", - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - } - }, - "@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", - "requires": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", - "debug": "^4.3.1", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", - "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3" - }, - "@csstools/normalize.css": { - "version": "12.0.0" - }, - "@csstools/postcss-cascade-layers": { - "version": "1.0.3", - "requires": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - } - }, - "@csstools/postcss-color-function": { - "version": "1.1.0", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-font-format-keywords": { - "version": "1.0.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-hwb-function": { - "version": "1.0.1", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-ic-unit": { - "version": "1.0.0", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-is-pseudo-class": { - "version": "2.0.5", - "requires": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - } - }, - "@csstools/postcss-normalize-display-values": { - "version": "1.0.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-oklab-function": { - "version": "1.1.0", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-progressive-custom-properties": { - "version": "1.3.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-stepped-value-functions": { - "version": "1.0.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-trigonometric-functions": { - "version": "1.0.1", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "@csstools/postcss-unset-value": { - "version": "1.0.1", - "requires": {} - }, - "@csstools/selector-specificity": { - "version": "2.0.0", - "requires": {} - }, - "@emotion/babel-plugin": { - "version": "11.10.5", - "requires": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.1", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.1.3" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0" - }, - "source-map": { - "version": "0.5.7" - } - } - }, - "@emotion/cache": { - "version": "11.10.5", - "requires": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.1", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.1.3" - } - }, - "@emotion/hash": { - "version": "0.9.0" - }, - "@emotion/is-prop-valid": { - "version": "1.2.0", - "requires": { - "@emotion/memoize": "^0.8.0" - } - }, - "@emotion/memoize": { - "version": "0.8.0" - }, - "@emotion/react": { - "version": "11.10.5", - "requires": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", - "@emotion/cache": "^11.10.5", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "hoist-non-react-statics": "^3.3.1" - } - }, - "@emotion/serialize": { - "version": "1.1.1", - "requires": { - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/unitless": "^0.8.0", - "@emotion/utils": "^1.2.0", - "csstype": "^3.0.2" - } - }, - "@emotion/sheet": { - "version": "1.2.1" - }, - "@emotion/styled": { - "version": "11.10.5", - "requires": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.5", - "@emotion/is-prop-valid": "^1.2.0", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0" - } - }, - "@emotion/unitless": { - "version": "0.8.0" - }, - "@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.0", - "requires": {} - }, - "@emotion/utils": { - "version": "1.2.0" - }, - "@emotion/weak-memoize": { - "version": "0.3.0" - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "globals": { - "version": "13.15.0", - "requires": { - "type-fest": "^0.20.2" - } - }, - "type-fest": { - "version": "0.20.2" - } - } - }, - "@formatjs/ecma402-abstract": { - "version": "1.11.4", - "requires": { - "@formatjs/intl-localematcher": "0.2.25", - "tslib": "^2.1.0" - } - }, - "@formatjs/fast-memoize": { - "version": "1.2.1", - "requires": { - "tslib": "^2.1.0" - } - }, - "@formatjs/icu-messageformat-parser": { - "version": "2.1.0", - "requires": { - "@formatjs/ecma402-abstract": "1.11.4", - "@formatjs/icu-skeleton-parser": "1.3.6", - "tslib": "^2.1.0" - } - }, - "@formatjs/icu-skeleton-parser": { - "version": "1.3.6", - "requires": { - "@formatjs/ecma402-abstract": "1.11.4", - "tslib": "^2.1.0" - } - }, - "@formatjs/intl": { - "version": "2.2.1", - "requires": { - "@formatjs/ecma402-abstract": "1.11.4", - "@formatjs/fast-memoize": "1.2.1", - "@formatjs/icu-messageformat-parser": "2.1.0", - "@formatjs/intl-displaynames": "5.4.3", - "@formatjs/intl-listformat": "6.5.3", - "intl-messageformat": "9.13.0", - "tslib": "^2.1.0" - } - }, - "@formatjs/intl-displaynames": { - "version": "5.4.3", - "requires": { - "@formatjs/ecma402-abstract": "1.11.4", - "@formatjs/intl-localematcher": "0.2.25", - "tslib": "^2.1.0" - } - }, - "@formatjs/intl-listformat": { - "version": "6.5.3", - "requires": { - "@formatjs/ecma402-abstract": "1.11.4", - "@formatjs/intl-localematcher": "0.2.25", - "tslib": "^2.1.0" - } - }, - "@formatjs/intl-localematcher": { - "version": "0.2.25", - "requires": { - "tslib": "^2.1.0" - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1" - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1" - }, - "find-up": { - "version": "4.1.0", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0" - }, - "path-exists": { - "version": "4.0.0" - }, - "resolve-from": { - "version": "5.0.0" - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3" - }, - "@jest/console": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/core": { - "version": "27.5.1", - "requires": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/environment": { - "version": "27.5.1", - "requires": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - } - }, - "@jest/fake-timers": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "@jest/globals": { - "version": "27.5.1", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - } - }, - "@jest/reporters": { - "version": "27.5.1", - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/schemas": { - "version": "28.0.2", - "requires": { - "@sinclair/typebox": "^0.23.3" - } - }, - "@jest/source-map": { - "version": "27.5.1", - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "27.5.1", - "requires": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.5.1", - "requires": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - } - }, - "@jest/transform": { - "version": "27.5.1", - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/types": { - "version": "27.5.1", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" - }, - "@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" - }, - "@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.4" - }, - "@mui/base": { - "version": "5.0.0-alpha.105", - "requires": { - "@babel/runtime": "^7.19.0", - "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", - "@popperjs/core": "^2.11.6", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" - }, - "dependencies": { - "react-is": { - "version": "18.2.0" - } - } - }, - "@mui/core-downloads-tracker": { - "version": "5.10.13" - }, - "@mui/material": { - "version": "5.10.13", - "requires": { - "@babel/runtime": "^7.19.0", - "@mui/base": "5.0.0-alpha.105", - "@mui/core-downloads-tracker": "^5.10.13", - "@mui/system": "^5.10.13", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", - "@types/react-transition-group": "^4.4.5", - "clsx": "^1.2.1", - "csstype": "^3.1.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0", - "react-transition-group": "^4.4.5" - }, - "dependencies": { - "react-is": { - "version": "18.2.0" - } - } - }, - "@mui/private-theming": { - "version": "5.10.9", - "requires": { - "@babel/runtime": "^7.19.0", - "@mui/utils": "^5.10.9", - "prop-types": "^15.8.1" - } - }, - "@mui/styled-engine": { - "version": "5.10.8", - "requires": { - "@babel/runtime": "^7.19.0", - "@emotion/cache": "^11.10.3", - "csstype": "^3.1.1", - "prop-types": "^15.8.1" - } - }, - "@mui/system": { - "version": "5.10.13", - "requires": { - "@babel/runtime": "^7.19.0", - "@mui/private-theming": "^5.10.9", - "@mui/styled-engine": "^5.10.8", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", - "clsx": "^1.2.1", - "csstype": "^3.1.1", - "prop-types": "^15.8.1" - } - }, - "@mui/types": { - "version": "7.2.0", - "requires": {} - }, - "@mui/utils": { - "version": "5.10.9", - "requires": { - "@babel/runtime": "^7.19.0", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" - }, - "dependencies": { - "react-is": { - "version": "18.2.0" - } - } - }, - "@mui/x-data-grid": { - "version": "5.17.10", - "requires": { - "@babel/runtime": "^7.18.9", - "@mui/utils": "^5.10.3", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "reselect": "^4.1.6" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.7", - "requires": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.8.1", - "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "find-up": { - "version": "5.0.0", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0" - }, - "source-map": { - "version": "0.7.4" - } - } - }, - "@popperjs/core": { - "version": "2.11.6" - }, - "@rollup/plugin-babel": { - "version": "5.3.1", - "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@rollup/pluginutils": "^3.1.0" - } - }, - "@rollup/plugin-node-resolve": { - "version": "11.2.1", - "requires": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - } - }, - "@rollup/plugin-replace": { - "version": "2.4.2", - "requires": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" - } - }, - "@rollup/pluginutils": { - "version": "3.1.0", - "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "dependencies": { - "@types/estree": { - "version": "0.0.39" - } - } - }, - "@rushstack/eslint-patch": { - "version": "1.1.3" - }, - "@sinclair/typebox": { - "version": "0.23.5" - }, - "@sinonjs/commons": { - "version": "1.8.3", - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "8.1.0", - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@surma/rollup-plugin-off-main-thread": { - "version": "2.2.3", - "requires": { - "ejs": "^3.1.6", - "json5": "^2.2.0", - "magic-string": "^0.25.0", - "string.prototype.matchall": "^4.0.6" - } - }, - "@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0" - }, - "@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0" - }, - "@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "5.0.1" - }, - "@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "5.0.1" - }, - "@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0" - }, - "@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0" - }, - "@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0" - }, - "@svgr/babel-plugin-transform-svg-component": { - "version": "5.5.0" - }, - "@svgr/babel-preset": { - "version": "5.5.0", - "requires": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.5.0" - } - }, - "@svgr/core": { - "version": "5.5.0", - "requires": { - "@svgr/plugin-jsx": "^5.5.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.0" - } - }, - "@svgr/hast-util-to-babel-ast": { - "version": "5.5.0", - "requires": { - "@babel/types": "^7.12.6" - } - }, - "@svgr/plugin-jsx": { - "version": "5.5.0", - "requires": { - "@babel/core": "^7.12.3", - "@svgr/babel-preset": "^5.5.0", - "@svgr/hast-util-to-babel-ast": "^5.5.0", - "svg-parser": "^2.0.2" - } - }, - "@svgr/plugin-svgo": { - "version": "5.5.0", - "requires": { - "cosmiconfig": "^7.0.0", - "deepmerge": "^4.2.2", - "svgo": "^1.2.2" - } - }, - "@svgr/webpack": { - "version": "5.5.0", - "requires": { - "@babel/core": "^7.12.3", - "@babel/plugin-transform-react-constant-elements": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-react": "^7.12.5", - "@svgr/core": "^5.5.0", - "@svgr/plugin-jsx": "^5.5.0", - "@svgr/plugin-svgo": "^5.5.0", - "loader-utils": "^2.0.0" - } - }, - "@tootallnate/once": { - "version": "1.1.2" - }, - "@trysound/sax": { - "version": "0.2.0" - }, - "@types/babel__core": { - "version": "7.1.19", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.17.1", - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/body-parser": { - "version": "1.19.2", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bonjour": { - "version": "3.5.10", - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "requires": { - "@types/node": "*" - } - }, - "@types/connect-history-api-fallback": { - "version": "1.3.5", - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "@types/eslint": { - "version": "7.29.0", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.3", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" - }, - "@types/express": { - "version": "4.17.13", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.28", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.5", - "requires": { - "@types/node": "*" - } - }, - "@types/hoist-non-react-statics": { - "version": "3.3.1", - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "@types/html-minifier-terser": { - "version": "6.1.0" - }, - "@types/http-proxy": { - "version": "1.17.9", - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4" - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/json-schema": { - "version": "7.0.11" - }, - "@types/json5": { - "version": "0.0.29" - }, - "@types/mime": { - "version": "1.3.2" - }, - "@types/node": { - "version": "17.0.41" - }, - "@types/parse-json": { - "version": "4.0.0" - }, - "@types/prettier": { - "version": "2.6.3" - }, - "@types/prop-types": { - "version": "15.7.5" - }, - "@types/q": { - "version": "1.5.5" - }, - "@types/qs": { - "version": "6.9.7" - }, - "@types/range-parser": { - "version": "1.2.4" - }, - "@types/react": { - "version": "18.0.12", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-is": { - "version": "17.0.3", - "requires": { - "@types/react": "*" - } - }, - "@types/react-transition-group": { - "version": "4.4.5", - "requires": { - "@types/react": "*" - } - }, - "@types/resolve": { - "version": "1.17.1", - "requires": { - "@types/node": "*" - } - }, - "@types/retry": { - "version": "0.12.0" - }, - "@types/scheduler": { - "version": "0.16.2" - }, - "@types/serve-index": { - "version": "1.9.1", - "requires": { - "@types/express": "*" - } - }, - "@types/serve-static": { - "version": "1.13.10", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/sockjs": { - "version": "0.3.33", - "requires": { - "@types/node": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.1" - }, - "@types/trusted-types": { - "version": "2.0.2" - }, - "@types/ws": { - "version": "8.5.3", - "requires": { - "@types/node": "*" - } - }, - "@types/yargs": { - "version": "16.0.4", - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0" - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.27.1", - "requires": { - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/type-utils": "5.27.1", - "@typescript-eslint/utils": "5.27.1", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "dependencies": { - "ignore": { - "version": "5.2.0" - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "@typescript-eslint/experimental-utils": { - "version": "5.27.1", - "requires": { - "@typescript-eslint/utils": "5.27.1" - } - }, - "@typescript-eslint/parser": { - "version": "5.27.1", - "requires": { - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/typescript-estree": "5.27.1", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.27.1", - "requires": { - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/visitor-keys": "5.27.1" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.27.1", - "requires": { - "@typescript-eslint/utils": "5.27.1", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.27.1" - }, - "@typescript-eslint/typescript-estree": { - "version": "5.27.1", - "requires": { - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/visitor-keys": "5.27.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "dependencies": { - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "@typescript-eslint/utils": { - "version": "5.27.1", - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/typescript-estree": "5.27.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - } - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.27.1", - "requires": { - "@typescript-eslint/types": "5.27.1", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.3.0" - } - } - }, - "@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "abab": { - "version": "2.0.6" - }, - "accepts": { - "version": "1.3.8", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "7.4.1" - }, - "acorn-globals": { - "version": "6.0.0", - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "acorn-jsx": { - "version": "5.3.2", - "requires": {} - }, - "acorn-node": { - "version": "1.8.2", - "requires": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - } - }, - "acorn-walk": { - "version": "7.2.0" - }, - "address": { - "version": "1.2.0" - }, - "adjust-sourcemap-loader": { - "version": "4.0.0", - "requires": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - } - }, - "agent-base": { - "version": "6.0.2", - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "requires": { - "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0" - } - } - }, - "ajv-keywords": { - "version": "3.5.2", - "requires": {} - }, - "ansi-colors": { - "version": "4.1.3" - }, - "ansi-escapes": { - "version": "4.3.2", - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-html-community": { - "version": "0.0.8" - }, - "ansi-regex": { - "version": "5.0.1" - }, - "ansi-styles": { - "version": "3.2.1", - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.2", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "5.0.2" - }, - "argparse": { - "version": "1.0.10", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-flatten": { - "version": "2.1.2" - }, - "array-includes": { - "version": "3.1.5", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0" - }, - "array.prototype.flat": { - "version": "1.3.0", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.0", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.reduce": { - "version": "1.0.4", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - } - }, - "asap": { - "version": "2.0.6" - }, - "ast-types-flow": { - "version": "0.0.7" - }, - "astral-regex": { - "version": "2.0.0" - }, - "async": { - "version": "3.2.4" - }, - "asynckit": { - "version": "0.4.0" - }, - "at-least-node": { - "version": "1.0.0" - }, - "autoprefixer": { - "version": "10.4.7", - "requires": { - "browserslist": "^4.20.3", - "caniuse-lite": "^1.0.30001335", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "axe-core": { - "version": "4.4.2" - }, - "axobject-query": { - "version": "2.2.0" - }, - "babel-jest": { - "version": "27.5.1", - "requires": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "babel-loader": { - "version": "8.2.5", - "requires": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "dependencies": { - "schema-utils": { - "version": "2.7.1", - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "27.5.1", - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-plugin-macros": { - "version": "3.1.0", - "requires": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - } - }, - "babel-plugin-named-asset-import": { - "version": "0.3.8", - "requires": {} - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.1", - "requires": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.1", - "semver": "^6.1.1" - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.5.2", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.1", - "core-js-compat": "^3.21.0" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.3.1", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.1" - } - }, - "babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.24" - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "27.5.1", - "requires": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "babel-preset-react-app": { - "version": "10.0.1", - "requires": { - "@babel/core": "^7.16.0", - "@babel/plugin-proposal-class-properties": "^7.16.0", - "@babel/plugin-proposal-decorators": "^7.16.4", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", - "@babel/plugin-proposal-numeric-separator": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-private-methods": "^7.16.0", - "@babel/plugin-transform-flow-strip-types": "^7.16.0", - "@babel/plugin-transform-react-display-name": "^7.16.0", - "@babel/plugin-transform-runtime": "^7.16.4", - "@babel/preset-env": "^7.16.4", - "@babel/preset-react": "^7.16.0", - "@babel/preset-typescript": "^7.16.0", - "@babel/runtime": "^7.16.3", - "babel-plugin-macros": "^3.1.0", - "babel-plugin-transform-react-remove-prop-types": "^0.4.24" - } - }, - "balanced-match": { - "version": "1.0.2" - }, - "batch": { - "version": "0.6.1" - }, - "bfj": { - "version": "7.0.2", - "requires": { - "bluebird": "^3.5.5", - "check-types": "^11.1.1", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" - } - }, - "big.js": { - "version": "5.2.2" - }, - "binary-extensions": { - "version": "2.2.0" - }, - "bluebird": { - "version": "3.7.2" - }, - "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "bonjour-service": { - "version": "1.0.13", - "requires": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "boolbase": { - "version": "1.0.0" - }, - "brace-expansion": { - "version": "1.1.11", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0" - }, - "browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", - "requires": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" - } - }, - "bser": { - "version": "2.1.1", - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.2" - }, - "builtin-modules": { - "version": "3.3.0" - }, - "bytes": { - "version": "3.0.0" - }, - "call-bind": { - "version": "1.0.2", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0" - }, - "camel-case": { - "version": "4.1.2", - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "camelcase": { - "version": "6.3.0" - }, - "camelcase-css": { - "version": "2.0.1" - }, - "caniuse-api": { - "version": "3.0.0", - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001551", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001551.tgz", - "integrity": "sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==" - }, - "case-sensitive-paths-webpack-plugin": { - "version": "2.4.0" - }, - "chalk": { - "version": "2.4.2", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "char-regex": { - "version": "1.0.2" - }, - "charcodes": { - "version": "0.2.0" - }, - "check-types": { - "version": "11.1.2" - }, - "chokidar": { - "version": "3.5.3", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chrome-trace-event": { - "version": "1.0.3" - }, - "ci-info": { - "version": "3.3.1" - }, - "cjs-module-lexer": { - "version": "1.2.2" - }, - "clean-css": { - "version": "5.3.0", - "requires": { - "source-map": "~0.6.0" - } - }, - "cliui": { - "version": "7.0.4", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "clsx": { - "version": "1.2.1" - }, - "co": { - "version": "4.6.0" - }, - "coa": { - "version": "2.0.2", - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - } - }, - "collect-v8-coverage": { - "version": "1.0.1" - }, - "color-convert": { - "version": "1.9.3", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3" - }, - "colord": { - "version": "2.9.2" - }, - "colorette": { - "version": "2.0.17" - }, - "combined-stream": { - "version": "1.0.8", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "8.3.0" - }, - "common-path-prefix": { - "version": "3.0.0" - }, - "common-tags": { - "version": "1.8.2" - }, - "commondir": { - "version": "1.0.1" - }, - "compressible": { - "version": "2.0.18", - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - } - } - }, - "concat-map": { - "version": "0.0.1" - }, - "confusing-browser-globals": { - "version": "1.0.11" - }, - "connect-history-api-fallback": { - "version": "1.6.0" - }, - "content-disposition": { - "version": "0.5.4", - "requires": { - "safe-buffer": "5.2.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1" - } - } - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "convert-source-map": { - "version": "1.8.0", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" - }, - "cookie-signature": { - "version": "1.0.6" - }, - "core-js": { - "version": "3.22.8" - }, - "core-js-compat": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", - "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", - "requires": { - "browserslist": "^4.22.1" - } - }, - "core-js-pure": { - "version": "3.22.8" - }, - "core-util-is": { - "version": "1.0.3" - }, - "cosmiconfig": { - "version": "7.0.1", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-random-string": { - "version": "2.0.0" - }, - "css-blank-pseudo": { - "version": "3.0.3", - "requires": { - "postcss-selector-parser": "^6.0.9" - } - }, - "css-declaration-sorter": { - "version": "6.2.2", - "requires": {} - }, - "css-has-pseudo": { - "version": "3.0.4", - "requires": { - "postcss-selector-parser": "^6.0.9" - } - }, - "css-loader": { - "version": "6.7.1", - "requires": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.7", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.5" - }, - "dependencies": { - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "css-minimizer-webpack-plugin": { - "version": "3.4.1", - "requires": { - "cssnano": "^5.0.6", - "jest-worker": "^27.0.2", - "postcss": "^8.3.5", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0" - }, - "schema-utils": { - "version": "4.0.0", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - } - } - }, - "css-prefers-color-scheme": { - "version": "6.0.3", - "requires": {} - }, - "css-select": { - "version": "4.3.0", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-select-base-adapter": { - "version": "0.1.1" - }, - "css-tree": { - "version": "1.0.0-alpha.37", - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - } - }, - "css-what": { - "version": "6.1.0" - }, - "cssdb": { - "version": "6.6.3" - }, - "cssesc": { - "version": "3.0.0" - }, - "cssnano": { - "version": "5.1.11", - "requires": { - "cssnano-preset-default": "^5.2.11", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - } - }, - "cssnano-preset-default": { - "version": "5.2.11", - "requires": { - "css-declaration-sorter": "^6.2.2", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", - "postcss-convert-values": "^5.1.2", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.5", - "postcss-merge-rules": "^5.1.2", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.3", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.0", - "postcss-normalize-repeat-style": "^5.1.0", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.0", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.2", - "postcss-reduce-initial": "^5.1.0", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - } - }, - "cssnano-utils": { - "version": "3.1.0", - "requires": {} - }, - "csso": { - "version": "4.2.0", - "requires": { - "css-tree": "^1.1.2" - }, - "dependencies": { - "css-tree": { - "version": "1.1.3", - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.14" - } - } - }, - "cssom": { - "version": "0.4.4" - }, - "cssstyle": { - "version": "2.3.0", - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8" - } - } - }, - "csstype": { - "version": "3.1.1" - }, - "damerau-levenshtein": { - "version": "1.0.8" - }, - "data-urls": { - "version": "2.0.0", - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "debug": { - "version": "4.3.4", - "requires": { - "ms": "2.1.2" - } - }, - "decimal.js": { - "version": "10.3.1" - }, - "dedent": { - "version": "0.7.0" - }, - "deep-is": { - "version": "0.1.4" - }, - "deepmerge": { - "version": "4.2.2" - }, - "default-gateway": { - "version": "6.0.3", - "requires": { - "execa": "^5.0.0" - } - }, - "define-lazy-prop": { - "version": "2.0.0" - }, - "define-properties": { - "version": "1.1.4", - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "defined": { - "version": "1.0.0" - }, - "delayed-stream": { - "version": "1.0.0" - }, - "depd": { - "version": "2.0.0" - }, - "destroy": { - "version": "1.2.0" - }, - "detect-newline": { - "version": "3.1.0" - }, - "detect-node": { - "version": "2.1.0" - }, - "detect-port-alt": { - "version": "1.1.6", - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - } - } - }, - "detective": { - "version": "5.2.1", - "requires": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - } - }, - "didyoumean": { - "version": "1.2.2" - }, - "diff-sequences": { - "version": "27.5.1" - }, - "dir-glob": { - "version": "3.0.1", - "requires": { - "path-type": "^4.0.0" - } - }, - "dlv": { - "version": "1.1.3" - }, - "dns-equal": { - "version": "1.0.0" - }, - "dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "requires": { - "@leichtgewicht/ip-codec": "^2.0.1" - } - }, - "doctrine": { - "version": "3.0.0", - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-converter": { - "version": "0.2.0", - "requires": { - "utila": "~0.4" - } - }, - "dom-helpers": { - "version": "5.2.1", - "requires": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "dom-serializer": { - "version": "1.4.1", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.3.0" - }, - "domexception": { - "version": "2.0.1", - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0" - } - } - }, - "domhandler": { - "version": "4.3.1", - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "dot-case": { - "version": "3.0.4", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "dotenv": { - "version": "10.0.0" - }, - "dotenv-expand": { - "version": "5.1.0" - }, - "duplexer": { - "version": "0.1.2" - }, - "ee-first": { - "version": "1.1.1" - }, - "ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "requires": { - "jake": "^10.8.5" - } - }, - "electron-to-chromium": { - "version": "1.4.559", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.559.tgz", - "integrity": "sha512-iS7KhLYCSJbdo3rUSkhDTVuFNCV34RKs2UaB9Ecr7VlqzjjWW//0nfsFF5dtDmyXlZQaDYYtID5fjtC/6lpRug==" - }, - "emittery": { - "version": "0.8.1" - }, - "emoji-regex": { - "version": "9.2.2" - }, - "emojis-list": { - "version": "3.0.0" - }, - "encodeurl": { - "version": "1.0.2" - }, - "enhanced-resolve": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", - "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "enquirer": { - "version": "2.3.6", - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "entities": { - "version": "2.2.0" - }, - "error-ex": { - "version": "1.3.2", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "error-stack-parser": { - "version": "2.1.4", - "requires": { - "stackframe": "^1.3.4" - } - }, - "es-abstract": { - "version": "1.20.1", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0" - }, - "es-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", - "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==" - }, - "es-shim-unscopables": { - "version": "1.0.0", - "requires": { - "has": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1" - }, - "escape-html": { - "version": "1.0.3" - }, - "escape-string-regexp": { - "version": "1.0.5" - }, - "escodegen": { - "version": "2.0.0", - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "levn": { - "version": "0.3.0", - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2" - }, - "type-check": { - "version": "0.3.2", - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "7.32.0", - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "escape-string-regexp": { - "version": "4.0.0" - }, - "globals": { - "version": "13.15.0", - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0" - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - }, - "type-fest": { - "version": "0.20.2" - } - } - }, - "eslint-config-airbnb": { - "version": "18.2.1", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^14.2.1", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - } - }, - "eslint-config-airbnb-base": { - "version": "14.2.1", - "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.7.3", - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.26.0", - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0" - } - } - }, - "eslint-plugin-jest": { - "version": "25.7.0", - "requires": { - "@typescript-eslint/experimental-utils": "^5.0.0" - } - }, - "eslint-plugin-jsx-a11y": { - "version": "6.5.1", - "requires": { - "@babel/runtime": "^7.16.3", - "aria-query": "^4.2.2", - "array-includes": "^3.1.4", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.3.5", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.7", - "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.2.1", - "language-tags": "^1.0.5", - "minimatch": "^3.0.4" - }, - "dependencies": { - "aria-query": { - "version": "4.2.2", - "requires": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - } - } - } - }, - "eslint-plugin-react": { - "version": "7.30.0", - "requires": { - "array-includes": "^3.1.5", - "array.prototype.flatmap": "^1.3.0", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.5", - "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.1", - "object.values": "^1.1.5", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.7" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "requires": { - "esutils": "^2.0.2" - } - }, - "resolve": { - "version": "2.0.0-next.3", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - } - } - }, - "eslint-plugin-react-hooks": { - "version": "4.5.0", - "requires": {} - }, - "eslint-plugin-testing-library": { - "version": "5.5.1", - "requires": { - "@typescript-eslint/utils": "^5.13.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0" - } - } - }, - "eslint-utils": { - "version": "2.1.0", - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0" - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0" - }, - "eslint-webpack-plugin": { - "version": "3.1.1", - "requires": { - "@types/eslint": "^7.28.2", - "jest-worker": "^27.3.1", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "schema-utils": "^3.1.1" - } - }, - "espree": { - "version": "7.3.1", - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0" - } - } - }, - "esprima": { - "version": "4.0.1" - }, - "esquery": { - "version": "1.4.0", - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0" - }, - "estree-walker": { - "version": "1.0.1" - }, - "esutils": { - "version": "2.0.3" - }, - "etag": { - "version": "1.8.1" - }, - "eventemitter3": { - "version": "4.0.7" - }, - "events": { - "version": "3.3.0" - }, - "execa": { - "version": "5.1.1", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2" - }, - "expect": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - } - }, - "express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1" - }, - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - }, - "safe-buffer": { - "version": "5.2.1" - } - } - }, - "fast-deep-equal": { - "version": "3.1.3" - }, - "fast-glob": { - "version": "3.2.11", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0" - }, - "fast-levenshtein": { - "version": "2.0.6" - }, - "fastq": { - "version": "1.13.0", - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fb-watchman": { - "version": "2.0.1", - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-loader": { - "version": "6.2.0", - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - } - }, - "filelist": { - "version": "1.0.4", - "requires": { - "minimatch": "^5.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.0", - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "filesize": { - "version": "8.0.7" - }, - "fill-range": { - "version": "7.0.1", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.2.0", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0" - } - } - }, - "find-cache-dir": { - "version": "3.3.2", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-root": { - "version": "1.1.0" - }, - "find-up": { - "version": "2.1.0", - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.5" - }, - "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" - }, - "fork-ts-checker-webpack-plugin": { - "version": "6.5.2", - "requires": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "cosmiconfig": { - "version": "6.0.0", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "fs-extra": { - "version": "9.1.0", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0" - }, - "schema-utils": { - "version": "2.7.0", - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - }, - "tapable": { - "version": "1.1.3" - } - } - }, - "form-data": { - "version": "3.0.1", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0" - }, - "fraction.js": { - "version": "4.2.0" - }, - "fresh": { - "version": "0.5.2" - }, - "fs-extra": { - "version": "10.1.0", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fs-monkey": { - "version": "1.0.3" - }, - "fs.realpath": { - "version": "1.0.0" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1" - }, - "function.prototype.name": { - "version": "1.1.5", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functional-red-black-tree": { - "version": "1.0.1" - }, - "functions-have-names": { - "version": "1.2.3" - }, - "gensync": { - "version": "1.0.0-beta.2" - }, - "get-caller-file": { - "version": "2.0.5" - }, - "get-intrinsic": { - "version": "1.1.1", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2" - }, - "get-package-type": { - "version": "0.1.0" - }, - "get-stream": { - "version": "6.0.1" - }, - "get-symbol-description": { - "version": "1.0.0", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.3", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "global-modules": { - "version": "2.0.0", - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "globals": { - "version": "11.12.0" - }, - "globby": { - "version": "11.1.0", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.2.0" - } - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "gzip-size": { - "version": "6.0.0", - "requires": { - "duplexer": "^0.1.2" - } - }, - "handle-thing": { - "version": "2.0.1" - }, - "harmony-reflect": { - "version": "1.6.2" - }, - "has": { - "version": "1.0.3", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.2" - }, - "has-flag": { - "version": "3.0.0" - }, - "has-property-descriptors": { - "version": "1.0.0", - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3" - }, - "has-tostringtag": { - "version": "1.0.0", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "he": { - "version": "1.2.0" - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "requires": { - "react-is": "^16.7.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1" - } - } - }, - "hoopy": { - "version": "0.1.4" - }, - "hpack.js": { - "version": "2.1.6", - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-entities": { - "version": "2.3.3" - }, - "html-escaper": { - "version": "2.0.2" - }, - "html-minifier-terser": { - "version": "6.1.0", - "requires": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - } - }, - "html-webpack-plugin": { - "version": "5.5.0", - "requires": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - } - }, - "htmlparser2": { - "version": "6.1.0", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "http-deceiver": { - "version": "1.2.7" - }, - "http-errors": { - "version": "2.0.0", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-parser-js": { - "version": "0.5.6" - }, - "http-proxy": { - "version": "1.18.1", - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-agent": { - "version": "4.0.1", - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "http-proxy-middleware": { - "version": "2.0.6", - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0" - }, - "iconv-lite": { - "version": "0.6.3", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "icss-utils": { - "version": "5.1.0", - "requires": {} - }, - "idb": { - "version": "6.1.5" - }, - "identity-obj-proxy": { - "version": "3.0.0", - "requires": { - "harmony-reflect": "^1.4.6" - } - }, - "ignore": { - "version": "4.0.6" - }, - "immer": { - "version": "9.0.14" - }, - "import-fresh": { - "version": "3.3.0", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-local": { - "version": "3.1.0", - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4" - }, - "inflight": { - "version": "1.0.6", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4" - }, - "ini": { - "version": "1.3.8" - }, - "internal-slot": { - "version": "1.0.3", - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "intl-messageformat": { - "version": "9.13.0", - "requires": { - "@formatjs/ecma402-abstract": "1.11.4", - "@formatjs/fast-memoize": "1.2.1", - "@formatjs/icu-messageformat-parser": "2.1.0", - "tslib": "^2.1.0" - } - }, - "ipaddr.js": { - "version": "2.0.1" - }, - "is-arrayish": { - "version": "0.2.1" - }, - "is-bigint": { - "version": "1.0.4", - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4" - }, - "is-core-module": { - "version": "2.9.0", - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-docker": { - "version": "2.2.1" - }, - "is-extglob": { - "version": "2.1.1" - }, - "is-fullwidth-code-point": { - "version": "3.0.0" - }, - "is-generator-fn": { - "version": "2.1.0" - }, - "is-glob": { - "version": "4.0.3", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-module": { - "version": "1.0.0" - }, - "is-negative-zero": { - "version": "2.0.2" - }, - "is-number": { - "version": "7.0.0" - }, - "is-number-object": { - "version": "1.0.7", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-obj": { - "version": "1.0.1" - }, - "is-plain-obj": { - "version": "3.0.0" - }, - "is-potential-custom-element-name": { - "version": "1.0.1" - }, - "is-regex": { - "version": "1.1.4", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-regexp": { - "version": "1.0.0" - }, - "is-root": { - "version": "2.1.0" - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-stream": { - "version": "2.0.1" - }, - "is-string": { - "version": "1.0.7", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typedarray": { - "version": "1.0.0" - }, - "is-weakref": { - "version": "1.0.2", - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-wsl": { - "version": "2.2.0", - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0" - }, - "isexe": { - "version": "2.0.0" - }, - "istanbul-lib-coverage": { - "version": "3.2.0" - }, - "istanbul-lib-instrument": { - "version": "5.2.0", - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.4", - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jake": { - "version": "10.8.5", - "requires": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest": { - "version": "27.5.1", - "requires": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - } - }, - "jest-changed-files": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.5.1", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-cli": { - "version": "27.5.1", - "requires": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-config": { - "version": "27.5.1", - "requires": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-diff": { - "version": "27.5.1", - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-docblock": { - "version": "27.5.1", - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-environment-jsdom": { - "version": "27.5.1", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.5.1", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "jest-get-type": { - "version": "27.5.1" - }, - "jest-haste-map": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.5.1", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-leak-detector": { - "version": "27.5.1", - "requires": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-matcher-utils": { - "version": "27.5.1", - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-message-util": { - "version": "27.5.1", - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-mock": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "requires": {} - }, - "jest-regex-util": { - "version": "27.5.1" - }, - "jest-resolve": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-resolve-dependencies": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - } - }, - "jest-runner": { - "version": "27.5.1", - "requires": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-runtime": { - "version": "27.5.1", - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-serializer": { - "version": "27.5.1", - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - } - }, - "jest-snapshot": { - "version": "27.5.1", - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-util": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-validate": { - "version": "27.5.1", - "requires": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-watch-typeahead": { - "version": "1.1.0", - "requires": { - "ansi-escapes": "^4.3.1", - "chalk": "^4.0.0", - "jest-regex-util": "^28.0.0", - "jest-watcher": "^28.0.0", - "slash": "^4.0.0", - "string-length": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "@jest/console": { - "version": "28.1.1", - "requires": { - "@jest/types": "^28.1.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^28.1.1", - "jest-util": "^28.1.1", - "slash": "^3.0.0" - }, - "dependencies": { - "slash": { - "version": "3.0.0" - } - } - }, - "@jest/test-result": { - "version": "28.1.1", - "requires": { - "@jest/console": "^28.1.1", - "@jest/types": "^28.1.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "28.1.1", - "requires": { - "@jest/schemas": "^28.0.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@types/yargs": { - "version": "17.0.10", - "requires": { - "@types/yargs-parser": "*" - } - }, - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "emittery": { - "version": "0.10.2" - }, - "has-flag": { - "version": "4.0.0" - }, - "jest-message-util": { - "version": "28.1.1", - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "slash": { - "version": "3.0.0" - } - } - }, - "jest-regex-util": { - "version": "28.0.2" - }, - "jest-util": { - "version": "28.1.1", - "requires": { - "@jest/types": "^28.1.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-watcher": { - "version": "28.1.1", - "requires": { - "@jest/test-result": "^28.1.1", - "@jest/types": "^28.1.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.1", - "string-length": "^4.0.1" - }, - "dependencies": { - "string-length": { - "version": "4.0.2", - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "pretty-format": { - "version": "28.1.1", - "requires": { - "@jest/schemas": "^28.0.2", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0" - } - } - }, - "react-is": { - "version": "18.1.0" - }, - "slash": { - "version": "4.0.0" - }, - "string-length": { - "version": "5.0.1", - "requires": { - "char-regex": "^2.0.0", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "char-regex": { - "version": "2.0.1" - } - } - }, - "strip-ansi": { - "version": "7.0.1", - "requires": { - "ansi-regex": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1" - } - } - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-watcher": { - "version": "27.5.1", - "requires": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-worker": { - "version": "27.5.1", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "8.1.1", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-tokens": { - "version": "4.0.0" - }, - "js-yaml": { - "version": "3.14.1", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsdom": { - "version": "16.7.0", - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "8.7.1" - } - } - }, - "jsesc": { - "version": "2.5.2" - }, - "json-parse-even-better-errors": { - "version": "2.3.1" - }, - "json-schema": { - "version": "0.4.0" - }, - "json-schema-traverse": { - "version": "0.4.1" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1" - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonfile": { - "version": "6.1.0", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "jsonpointer": { - "version": "5.0.0" - }, - "jsx-ast-utils": { - "version": "3.3.0", - "requires": { - "array-includes": "^3.1.4", - "object.assign": "^4.1.2" - } - }, - "kind-of": { - "version": "6.0.3" - }, - "kleur": { - "version": "3.0.3" - }, - "klona": { - "version": "2.0.5" - }, - "language-subtag-registry": { - "version": "0.3.21" - }, - "language-tags": { - "version": "1.0.5", - "requires": { - "language-subtag-registry": "~0.3.2" - } - }, - "leven": { - "version": "3.1.0" - }, - "levn": { - "version": "0.4.1", - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lilconfig": { - "version": "2.0.5" - }, - "lines-and-columns": { - "version": "1.2.4" - }, - "loader-runner": { - "version": "4.3.0" - }, - "loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "2.0.0", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21" - }, - "lodash.debounce": { - "version": "4.0.8" - }, - "lodash.memoize": { - "version": "4.1.2" - }, - "lodash.merge": { - "version": "4.6.2" - }, - "lodash.sortby": { - "version": "4.7.0" - }, - "lodash.truncate": { - "version": "4.4.2" - }, - "lodash.uniq": { - "version": "4.5.0" - }, - "loose-envify": { - "version": "1.4.0", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "2.0.2", - "requires": { - "tslib": "^2.0.3" - } - }, - "lru-cache": { - "version": "6.0.0", - "requires": { - "yallist": "^4.0.0" - } - }, - "magic-string": { - "version": "0.25.9", - "requires": { - "sourcemap-codec": "^1.4.8" - } - }, - "make-dir": { - "version": "3.1.0", - "requires": { - "semver": "^6.0.0" - } - }, - "makeerror": { - "version": "1.0.12", - "requires": { - "tmpl": "1.0.5" - } - }, - "mdn-data": { - "version": "2.0.4" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "memfs": { - "version": "3.4.4", - "requires": { - "fs-monkey": "1.0.3" - } - }, - "merge-descriptors": { - "version": "1.0.1" - }, - "merge-stream": { - "version": "2.0.0" - }, - "merge2": { - "version": "1.4.1" - }, - "methods": { - "version": "1.1.2" - }, - "micromatch": { - "version": "4.0.5", - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "1.6.0" - }, - "mime-db": { - "version": "1.52.0" - }, - "mime-types": { - "version": "2.1.35", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0" - }, - "mini-css-extract-plugin": { - "version": "2.6.0", - "requires": { - "schema-utils": "^4.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0" - }, - "schema-utils": { - "version": "4.0.0", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - } - } - }, - "minimalistic-assert": { - "version": "1.0.1" - }, - "minimatch": { - "version": "3.1.2", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6" - }, - "mkdirp": { - "version": "0.5.6", - "requires": { - "minimist": "^1.2.6" - } - }, - "ms": { - "version": "2.1.2" - }, - "multicast-dns": { - "version": "7.2.5", - "requires": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - } - }, - "nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" - }, - "natural-compare": { - "version": "1.4.0" - }, - "negotiator": { - "version": "0.6.3" - }, - "neo-async": { - "version": "2.6.2" - }, - "no-case": { - "version": "3.0.4", - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-forge": { - "version": "1.3.1" - }, - "node-int64": { - "version": "0.4.0" - }, - "node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" - }, - "normalize-path": { - "version": "3.0.0" - }, - "normalize-range": { - "version": "0.1.2" - }, - "normalize-url": { - "version": "6.1.0" - }, - "npm-run-path": { - "version": "4.0.1", - "requires": { - "path-key": "^3.0.0" - } - }, - "nth-check": { - "version": "2.1.1", - "requires": { - "boolbase": "^1.0.0" - } - }, - "nwsapi": { - "version": "2.2.0" - }, - "object-assign": { - "version": "4.1.1" - }, - "object-hash": { - "version": "3.0.0" - }, - "object-inspect": { - "version": "1.12.2" - }, - "object-keys": { - "version": "1.1.1" - }, - "object.assign": { - "version": "4.1.2", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.5", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.fromentries": { - "version": "2.0.5", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.4", - "requires": { - "array.prototype.reduce": "^1.0.4", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.1" - } - }, - "object.hasown": { - "version": "1.1.1", - "requires": { - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "object.values": { - "version": "1.1.5", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "obuf": { - "version": "1.1.2" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2" - }, - "once": { - "version": "1.4.0", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "8.4.0", - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "optionator": { - "version": "0.9.1", - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-limit": { - "version": "1.3.0", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-retry": { - "version": "4.6.2", - "requires": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - } - }, - "p-try": { - "version": "1.0.0" - }, - "param-case": { - "version": "3.0.4", - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "parent-module": { - "version": "1.0.1", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse5": { - "version": "6.0.1" - }, - "parseurl": { - "version": "1.3.3" - }, - "pascal-case": { - "version": "3.1.2", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "path-exists": { - "version": "3.0.0" - }, - "path-is-absolute": { - "version": "1.0.1" - }, - "path-key": { - "version": "3.1.1" - }, - "path-parse": { - "version": "1.0.7" - }, - "path-to-regexp": { - "version": "0.1.7" - }, - "path-type": { - "version": "4.0.0" - }, - "performance-now": { - "version": "2.1.0" - }, - "picocolors": { - "version": "1.0.0" - }, - "picomatch": { - "version": "2.3.1" - }, - "pirates": { - "version": "4.0.5" - }, - "pkg-dir": { - "version": "4.2.0", - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0" - }, - "path-exists": { - "version": "4.0.0" - } - } - }, - "pkg-up": { - "version": "3.1.0", - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0" - } - } - }, - "postcss": { - "version": "8.4.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.36.tgz", - "integrity": "sha512-/n7eumA6ZjFHAsbX30yhHup/IMkOmlmvtEi7P+6RMYf+bGJSUHc3geH4a0NSZxAz/RJfiS9tooCTs9LAVYUZKw==", - "requires": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.1.0" - } - }, - "postcss-attribute-case-insensitive": { - "version": "5.0.1", - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-browser-comments": { - "version": "4.0.0", - "requires": {} - }, - "postcss-calc": { - "version": "8.2.4", - "requires": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-clamp": { - "version": "4.1.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-color-functional-notation": { - "version": "4.2.3", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-color-hex-alpha": { - "version": "8.0.3", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-color-rebeccapurple": { - "version": "7.0.2", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-colormin": { - "version": "5.3.0", - "requires": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-convert-values": { - "version": "5.1.2", - "requires": { - "browserslist": "^4.20.3", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-custom-media": { - "version": "8.0.2", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-custom-properties": { - "version": "12.1.7", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-custom-selectors": { - "version": "6.0.3", - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-dir-pseudo-class": { - "version": "6.0.4", - "requires": { - "postcss-selector-parser": "^6.0.9" - } - }, - "postcss-discard-comments": { - "version": "5.1.2", - "requires": {} - }, - "postcss-discard-duplicates": { - "version": "5.1.0", - "requires": {} - }, - "postcss-discard-empty": { - "version": "5.1.1", - "requires": {} - }, - "postcss-discard-overridden": { - "version": "5.1.0", - "requires": {} - }, - "postcss-double-position-gradients": { - "version": "3.1.1", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-env-function": { - "version": "4.0.6", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-flexbugs-fixes": { - "version": "5.0.2", - "requires": {} - }, - "postcss-focus-visible": { - "version": "6.0.4", - "requires": { - "postcss-selector-parser": "^6.0.9" - } - }, - "postcss-focus-within": { - "version": "5.0.4", - "requires": { - "postcss-selector-parser": "^6.0.9" - } - }, - "postcss-font-variant": { - "version": "5.0.0", - "requires": {} - }, - "postcss-gap-properties": { - "version": "3.0.3", - "requires": {} - }, - "postcss-image-set-function": { - "version": "4.0.6", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-initial": { - "version": "4.0.1", - "requires": {} - }, - "postcss-js": { - "version": "4.0.0", - "requires": { - "camelcase-css": "^2.0.1" - } - }, - "postcss-lab-function": { - "version": "4.2.0", - "requires": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-load-config": { - "version": "3.1.4", - "requires": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" - } - }, - "postcss-loader": { - "version": "6.2.1", - "requires": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.5", - "semver": "^7.3.5" - }, - "dependencies": { - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "postcss-logical": { - "version": "5.0.4", - "requires": {} - }, - "postcss-media-minmax": { - "version": "5.0.0", - "requires": {} - }, - "postcss-merge-longhand": { - "version": "5.1.5", - "requires": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.0" - } - }, - "postcss-merge-rules": { - "version": "5.1.2", - "requires": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-minify-font-values": { - "version": "5.1.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-gradients": { - "version": "5.1.1", - "requires": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-params": { - "version": "5.1.3", - "requires": { - "browserslist": "^4.16.6", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-selectors": { - "version": "5.2.1", - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-modules-extract-imports": { - "version": "3.0.0", - "requires": {} - }, - "postcss-modules-local-by-default": { - "version": "4.0.0", - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.0.0", - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-nested": { - "version": "5.0.6", - "requires": { - "postcss-selector-parser": "^6.0.6" - } - }, - "postcss-nesting": { - "version": "10.1.8", - "requires": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-normalize": { - "version": "10.0.1", - "requires": { - "@csstools/normalize.css": "*", - "postcss-browser-comments": "^4", - "sanitize.css": "*" - } - }, - "postcss-normalize-charset": { - "version": "5.1.0", - "requires": {} - }, - "postcss-normalize-display-values": { - "version": "5.1.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-positions": { - "version": "5.1.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "5.1.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-string": { - "version": "5.1.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "5.1.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-unicode": { - "version": "5.1.0", - "requires": { - "browserslist": "^4.16.6", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-url": { - "version": "5.1.0", - "requires": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-whitespace": { - "version": "5.1.1", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-opacity-percentage": { - "version": "1.1.2" - }, - "postcss-ordered-values": { - "version": "5.1.2", - "requires": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-overflow-shorthand": { - "version": "3.0.3", - "requires": {} - }, - "postcss-page-break": { - "version": "3.0.4", - "requires": {} - }, - "postcss-place": { - "version": "7.0.4", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-preset-env": { - "version": "7.7.1", - "requires": { - "@csstools/postcss-cascade-layers": "^1.0.2", - "@csstools/postcss-color-function": "^1.1.0", - "@csstools/postcss-font-format-keywords": "^1.0.0", - "@csstools/postcss-hwb-function": "^1.0.1", - "@csstools/postcss-ic-unit": "^1.0.0", - "@csstools/postcss-is-pseudo-class": "^2.0.4", - "@csstools/postcss-normalize-display-values": "^1.0.0", - "@csstools/postcss-oklab-function": "^1.1.0", - "@csstools/postcss-progressive-custom-properties": "^1.3.0", - "@csstools/postcss-stepped-value-functions": "^1.0.0", - "@csstools/postcss-trigonometric-functions": "^1.0.1", - "@csstools/postcss-unset-value": "^1.0.1", - "autoprefixer": "^10.4.7", - "browserslist": "^4.20.3", - "css-blank-pseudo": "^3.0.3", - "css-has-pseudo": "^3.0.4", - "css-prefers-color-scheme": "^6.0.3", - "cssdb": "^6.6.3", - "postcss-attribute-case-insensitive": "^5.0.1", - "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^4.2.3", - "postcss-color-hex-alpha": "^8.0.3", - "postcss-color-rebeccapurple": "^7.0.2", - "postcss-custom-media": "^8.0.1", - "postcss-custom-properties": "^12.1.7", - "postcss-custom-selectors": "^6.0.2", - "postcss-dir-pseudo-class": "^6.0.4", - "postcss-double-position-gradients": "^3.1.1", - "postcss-env-function": "^4.0.6", - "postcss-focus-visible": "^6.0.4", - "postcss-focus-within": "^5.0.4", - "postcss-font-variant": "^5.0.0", - "postcss-gap-properties": "^3.0.3", - "postcss-image-set-function": "^4.0.6", - "postcss-initial": "^4.0.1", - "postcss-lab-function": "^4.2.0", - "postcss-logical": "^5.0.4", - "postcss-media-minmax": "^5.0.0", - "postcss-nesting": "^10.1.7", - "postcss-opacity-percentage": "^1.1.2", - "postcss-overflow-shorthand": "^3.0.3", - "postcss-page-break": "^3.0.4", - "postcss-place": "^7.0.4", - "postcss-pseudo-class-any-link": "^7.1.4", - "postcss-replace-overflow-wrap": "^4.0.0", - "postcss-selector-not": "^6.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-pseudo-class-any-link": { - "version": "7.1.4", - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-reduce-initial": { - "version": "5.1.0", - "requires": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "5.1.0", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-replace-overflow-wrap": { - "version": "4.0.0", - "requires": {} - }, - "postcss-selector-not": { - "version": "6.0.0", - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "postcss-selector-parser": { - "version": "6.0.10", - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-svgo": { - "version": "5.1.0", - "requires": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - }, - "dependencies": { - "commander": { - "version": "7.2.0" - }, - "css-tree": { - "version": "1.1.3", - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.14" - }, - "svgo": { - "version": "2.8.0", - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - } - } - } - }, - "postcss-unique-selectors": { - "version": "5.1.1", - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-value-parser": { - "version": "4.2.0" - }, - "prelude-ls": { - "version": "1.2.1" - }, - "pretty-bytes": { - "version": "5.6.0" - }, - "pretty-error": { - "version": "4.0.0", - "requires": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "pretty-format": { - "version": "27.5.1", - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0" - } - } - }, - "process-nextick-args": { - "version": "2.0.1" - }, - "progress": { - "version": "2.0.3" - }, - "promise": { - "version": "8.1.0", - "requires": { - "asap": "~2.0.6" - } - }, - "prompts": { - "version": "2.4.2", - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "prop-types": { - "version": "15.8.1", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1" - } - } - }, - "proxy-addr": { - "version": "2.0.7", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "dependencies": { - "ipaddr.js": { - "version": "1.9.1" - } - } - }, - "psl": { - "version": "1.8.0" - }, - "punycode": { - "version": "2.1.1" - }, - "q": { - "version": "1.5.1" - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "queue-microtask": { - "version": "1.2.3" - }, - "quick-lru": { - "version": "5.1.1" - }, - "raf": { - "version": "3.4.1", - "requires": { - "performance-now": "^2.1.0" - } - }, - "randombytes": { - "version": "2.1.0", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1" - }, - "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "react": { - "version": "17.0.2", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "react-app-polyfill": { - "version": "3.0.0", - "requires": { - "core-js": "^3.19.2", - "object-assign": "^4.1.1", - "promise": "^8.1.0", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.9", - "whatwg-fetch": "^3.6.2" - } - }, - "react-dev-utils": { - "version": "12.0.1", - "requires": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "escape-string-regexp": { - "version": "4.0.0" - }, - "find-up": { - "version": "5.0.0", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "has-flag": { - "version": "4.0.0" - }, - "loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" - }, - "locate-path": { - "version": "6.0.0", - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "react-dom": { - "version": "17.0.2", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - } - }, - "react-error-overlay": { - "version": "6.0.11" - }, - "react-intl": { - "version": "5.25.1", - "requires": { - "@formatjs/ecma402-abstract": "1.11.4", - "@formatjs/icu-messageformat-parser": "2.1.0", - "@formatjs/intl": "2.2.1", - "@formatjs/intl-displaynames": "5.4.3", - "@formatjs/intl-listformat": "6.5.3", - "@types/hoist-non-react-statics": "^3.3.1", - "@types/react": "16 || 17 || 18", - "hoist-non-react-statics": "^3.3.2", - "intl-messageformat": "9.13.0", - "tslib": "^2.1.0" - } - }, - "react-is": { - "version": "17.0.2" - }, - "react-refresh": { - "version": "0.11.0" - }, - "react-scripts": { - "version": "5.0.1", - "requires": { - "@babel/core": "^7.16.0", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", - "@svgr/webpack": "^5.5.0", - "babel-jest": "^27.4.2", - "babel-loader": "^8.2.3", - "babel-plugin-named-asset-import": "^0.3.8", - "babel-preset-react-app": "^10.0.1", - "bfj": "^7.0.2", - "browserslist": "^4.18.1", - "camelcase": "^6.2.1", - "case-sensitive-paths-webpack-plugin": "^2.4.0", - "css-loader": "^6.5.1", - "css-minimizer-webpack-plugin": "^3.2.0", - "dotenv": "^10.0.0", - "dotenv-expand": "^5.1.0", - "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.1", - "eslint-webpack-plugin": "^3.1.1", - "file-loader": "^6.2.0", - "fs-extra": "^10.0.0", - "fsevents": "^2.3.2", - "html-webpack-plugin": "^5.5.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^27.4.3", - "jest-resolve": "^27.4.2", - "jest-watch-typeahead": "^1.0.0", - "mini-css-extract-plugin": "^2.4.5", - "postcss": "^8.4.4", - "postcss-flexbugs-fixes": "^5.0.2", - "postcss-loader": "^6.2.1", - "postcss-normalize": "^10.0.1", - "postcss-preset-env": "^7.0.1", - "prompts": "^2.4.2", - "react-app-polyfill": "^3.0.0", - "react-dev-utils": "^12.0.1", - "react-refresh": "^0.11.0", - "resolve": "^1.20.0", - "resolve-url-loader": "^4.0.0", - "sass-loader": "^12.3.0", - "semver": "^7.3.5", - "source-map-loader": "^3.0.0", - "style-loader": "^3.3.1", - "tailwindcss": "^3.0.2", - "terser-webpack-plugin": "^5.2.5", - "webpack": "^5.64.4", - "webpack-dev-server": "^4.6.0", - "webpack-manifest-plugin": "^4.0.2", - "workbox-webpack-plugin": "^6.4.1" - }, - "dependencies": { - "@eslint/eslintrc": { - "version": "1.3.0", - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.9.5", - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "acorn": { - "version": "8.7.1" - }, - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1" - }, - "chalk": { - "version": "4.1.2", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - }, - "escape-string-regexp": { - "version": "4.0.0" - }, - "eslint": { - "version": "8.17.0", - "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.3.0" - } - } - }, - "eslint-config-react-app": { - "version": "7.0.1", - "requires": { - "@babel/core": "^7.16.0", - "@babel/eslint-parser": "^7.16.3", - "@rushstack/eslint-patch": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", - "babel-preset-react-app": "^10.0.1", - "confusing-browser-globals": "^1.0.11", - "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jest": "^25.3.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.27.1", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-testing-library": "^5.0.1" - } - }, - "eslint-plugin-flowtype": { - "version": "8.0.3", - "requires": { - "lodash": "^4.17.21", - "string-natural-compare": "^3.0.1" - } - }, - "eslint-scope": { - "version": "7.1.1", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "espree": { - "version": "9.3.2", - "requires": { - "acorn": "^8.7.1", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.3.0" - } - } - }, - "glob-parent": { - "version": "6.0.2", - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.15.0", - "requires": { - "type-fest": "^0.20.2" - } - }, - "has-flag": { - "version": "4.0.0" - }, - "ignore": { - "version": "5.2.0" - }, - "js-yaml": { - "version": "4.1.0", - "requires": { - "argparse": "^2.0.1" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - }, - "type-fest": { - "version": "0.20.2" - } - } - }, - "react-transition-group": { - "version": "4.4.5", - "requires": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - } - }, - "readable-stream": { - "version": "3.6.0", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "requires": { - "picomatch": "^2.2.1" - } - }, - "recursive-readdir": { - "version": "2.2.3", - "requires": { - "minimatch": "^3.0.5" - } - }, - "regenerate": { - "version": "1.4.2" - }, - "regenerate-unicode-properties": { - "version": "10.0.1", - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.13.10" - }, - "regenerator-transform": { - "version": "0.15.0", - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regex-parser": { - "version": "2.2.11" - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - } - }, - "regexpp": { - "version": "3.2.0" - }, - "regexpu-core": { - "version": "5.0.1", - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.0.1", - "regjsgen": "^0.6.0", - "regjsparser": "^0.8.2", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" - } - }, - "regjsgen": { - "version": "0.6.0" - }, - "regjsparser": { - "version": "0.8.4", - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0" - } - } - }, - "relateurl": { - "version": "0.2.7" - }, - "renderkid": { - "version": "3.0.0", - "requires": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "require-directory": { - "version": "2.1.1" - }, - "require-from-string": { - "version": "2.0.2" - }, - "requires-port": { - "version": "1.0.0" - }, - "reselect": { - "version": "4.1.7" - }, - "resolve": { - "version": "1.22.0", - "requires": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0" - } - } - }, - "resolve-from": { - "version": "4.0.0" - }, - "resolve-url-loader": { - "version": "4.0.0", - "requires": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^7.0.35", - "source-map": "0.6.1" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1" - }, - "postcss": { - "version": "7.0.39", - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - } - } - }, - "resolve.exports": { - "version": "1.1.0" - }, - "retry": { - "version": "0.13.1" - }, - "reusify": { - "version": "1.0.4" - }, - "rimraf": { - "version": "3.0.2", - "requires": { - "glob": "^7.1.3" - } - }, - "rollup": { - "version": "2.75.6", - "requires": { - "fsevents": "~2.3.2" - } - }, - "rollup-plugin-terser": { - "version": "7.0.2", - "requires": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^4.0.0", - "terser": "^5.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0" - }, - "jest-worker": { - "version": "26.6.2", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "serialize-javascript": { - "version": "4.0.0", - "requires": { - "randombytes": "^2.1.0" - } - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "run-parallel": { - "version": "1.2.0", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-buffer": { - "version": "5.1.2" - }, - "safer-buffer": { - "version": "2.1.2" - }, - "sanitize.css": { - "version": "13.0.0" - }, - "sass-loader": { - "version": "12.6.0", - "requires": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - } - }, - "sax": { - "version": "1.2.4" - }, - "saxes": { - "version": "5.0.1", - "requires": { - "xmlchars": "^2.2.0" - } - }, - "scheduler": { - "version": "0.20.2", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "select-hose": { - "version": "2.0.0" - }, - "selfsigned": { - "version": "2.0.1", - "requires": { - "node-forge": "^1" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - }, - "send": { - "version": "0.18.0", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0" - } - } - }, - "ms": { - "version": "2.1.3" - } - } - }, - "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2" - }, - "http-errors": { - "version": "1.6.3", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3" - }, - "ms": { - "version": "2.0.0" - }, - "setprototypeof": { - "version": "1.1.0" - }, - "statuses": { - "version": "1.5.0" - } - } - }, - "serve-static": { - "version": "1.15.0", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "setprototypeof": { - "version": "1.2.0" - }, - "shebang-command": { - "version": "2.0.0", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0" - }, - "shell-quote": { - "version": "1.7.3" - }, - "side-channel": { - "version": "1.0.4", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7" - }, - "sisteransi": { - "version": "1.0.5" - }, - "slash": { - "version": "3.0.0" - }, - "slice-ansi": { - "version": "4.0.0", - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - } - } - }, - "sockjs": { - "version": "0.3.24", - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "source-list-map": { - "version": "2.0.1" - }, - "source-map": { - "version": "0.6.1" - }, - "source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==" - }, - "source-map-loader": { - "version": "3.0.1", - "requires": { - "abab": "^2.0.5", - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.1" - } - }, - "source-map-support": { - "version": "0.5.21", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sourcemap-codec": { - "version": "1.4.8" - }, - "spdy": { - "version": "4.0.2", - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "sprintf-js": { - "version": "1.0.3" - }, - "stable": { - "version": "0.1.8" - }, - "stack-utils": { - "version": "2.0.5", - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0" - } - } - }, - "stackframe": { - "version": "1.3.4" - }, - "statuses": { - "version": "2.0.1" - }, - "string_decoder": { - "version": "1.3.0", - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1" - } - } - }, - "string-length": { - "version": "4.0.2", - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-natural-compare": { - "version": "3.0.1" - }, - "string-width": { - "version": "4.2.3", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0" - } - } - }, - "string.prototype.matchall": { - "version": "4.0.7", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.1", - "side-channel": "^1.0.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.5", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "string.prototype.trimstart": { - "version": "1.0.5", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" - } - }, - "stringify-object": { - "version": "3.3.0", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0" - }, - "strip-comments": { - "version": "2.0.1" - }, - "strip-final-newline": { - "version": "2.0.0" - }, - "strip-json-comments": { - "version": "3.1.1" - }, - "style-loader": { - "version": "3.3.1", - "requires": {} - }, - "stylehacks": { - "version": "5.1.0", - "requires": { - "browserslist": "^4.16.6", - "postcss-selector-parser": "^6.0.4" - } - }, - "stylis": { - "version": "4.1.3" - }, - "supports-color": { - "version": "5.5.0", - "requires": { - "has-flag": "^3.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.2.0", - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0" - }, - "supports-color": { - "version": "7.2.0", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0" - }, - "svg-parser": { - "version": "2.0.4" - }, - "svgo": { - "version": "1.3.2", - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "dependencies": { - "css-select": { - "version": "2.1.0", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-what": { - "version": "3.4.2" - }, - "dom-serializer": { - "version": "0.2.2", - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "domutils": { - "version": "1.7.0", - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - }, - "dependencies": { - "domelementtype": { - "version": "1.3.1" - } - } - }, - "nth-check": { - "version": "1.0.2", - "requires": { - "boolbase": "~1.0.0" - } - } - } - }, - "symbol-tree": { - "version": "3.2.4" - }, - "table": { - "version": "6.8.0", - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0" - } - } - }, - "tailwindcss": { - "version": "3.0.24", - "requires": { - "arg": "^5.0.1", - "chokidar": "^3.5.3", - "color-name": "^1.1.4", - "detective": "^5.2.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "lilconfig": "^2.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.12", - "postcss-js": "^4.0.0", - "postcss-load-config": "^3.1.4", - "postcss-nested": "5.0.6", - "postcss-selector-parser": "^6.0.10", - "postcss-value-parser": "^4.2.0", - "quick-lru": "^5.1.1", - "resolve": "^1.22.0" - }, - "dependencies": { - "color-name": { - "version": "1.1.4" - }, - "glob-parent": { - "version": "6.0.2", - "requires": { - "is-glob": "^4.0.3" - } - } - } - }, - "tapable": { - "version": "2.2.1" - }, - "temp-dir": { - "version": "2.0.0" - }, - "tempy": { - "version": "0.6.0", - "requires": { - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "dependencies": { - "type-fest": { - "version": "0.16.0" - } - } - }, - "terminal-link": { - "version": "2.1.1", - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "terser": { - "version": "5.30.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", - "integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" - }, - "commander": { - "version": "2.20.3" - } - } - }, - "terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "requires": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - } - }, - "test-exclude": { - "version": "6.0.0", - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0" - }, - "throat": { - "version": "6.0.1" - }, - "thunky": { - "version": "1.1.0" - }, - "tmpl": { - "version": "1.0.5" - }, - "to-fast-properties": { - "version": "2.0.0" - }, - "to-regex-range": { - "version": "5.0.1", - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1" - }, - "tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "dependencies": { - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" - } - } - }, - "tr46": { - "version": "2.1.0", - "requires": { - "punycode": "^2.1.1" - } - }, - "tryer": { - "version": "1.0.1" - }, - "tsconfig-paths": { - "version": "3.14.1", - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0" - } - } - }, - "tslib": { - "version": "2.4.0" - }, - "tsutils": { - "version": "3.21.0", - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1" - } - } - }, - "type-check": { - "version": "0.4.0", - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8" - }, - "type-fest": { - "version": "0.21.3" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.7.3", - "peer": true - }, - "unbox-primitive": { - "version": "1.0.2", - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0" - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.0.0" - }, - "unicode-property-aliases-ecmascript": { - "version": "2.0.0" - }, - "unique-string": { - "version": "2.0.0", - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0" - }, - "unpipe": { - "version": "1.0.0" - }, - "unquote": { - "version": "1.1.1" - }, - "upath": { - "version": "1.2.0" - }, - "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2" - }, - "util.promisify": { - "version": "1.0.1", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, - "utila": { - "version": "0.4.0" - }, - "utils-merge": { - "version": "1.0.1" - }, - "uuid": { - "version": "8.3.2" - }, - "v8-compile-cache": { - "version": "2.3.0" - }, - "v8-to-istanbul": { - "version": "8.1.1", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.4" - } - } - }, - "vary": { - "version": "1.1.2" - }, - "w3c-hr-time": { - "version": "1.0.2", - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walker": { - "version": "1.0.8", - "requires": { - "makeerror": "1.0.12" - } - }, - "watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webidl-conversions": { - "version": "6.1.0" - }, - "webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", - "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "dependencies": { - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" - }, - "acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "requires": {} - } - } - }, - "webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "requires": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0" - }, - "schema-utils": { - "version": "4.0.0", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - } - } - }, - "webpack-dev-server": { - "version": "4.9.2", - "requires": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.0.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0" - }, - "schema-utils": { - "version": "4.0.0", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - }, - "ws": { - "version": "8.7.0", - "requires": {} - } - } - }, - "webpack-manifest-plugin": { - "version": "4.1.1", - "requires": { - "tapable": "^2.0.0", - "webpack-sources": "^2.2.0" - }, - "dependencies": { - "webpack-sources": { - "version": "2.3.1", - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - } - } - }, - "webpack-sources": { - "version": "3.2.3" - }, - "websocket-driver": { - "version": "0.7.4", - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4" - }, - "whatwg-encoding": { - "version": "1.0.5", - "requires": { - "iconv-lite": "0.4.24" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "whatwg-fetch": { - "version": "3.6.2" - }, - "whatwg-mimetype": { - "version": "2.3.0" - }, - "whatwg-url": { - "version": "8.7.0", - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "which": { - "version": "2.0.2", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==" - }, - "workbox-background-sync": { - "version": "6.5.3", - "requires": { - "idb": "^6.1.4", - "workbox-core": "6.5.3" - } - }, - "workbox-broadcast-update": { - "version": "6.5.3", - "requires": { - "workbox-core": "6.5.3" - } - }, - "workbox-build": { - "version": "6.5.3", - "requires": { - "@apideck/better-ajv-errors": "^0.3.1", - "@babel/core": "^7.11.1", - "@babel/preset-env": "^7.11.0", - "@babel/runtime": "^7.11.2", - "@rollup/plugin-babel": "^5.2.0", - "@rollup/plugin-node-resolve": "^11.2.1", - "@rollup/plugin-replace": "^2.4.1", - "@surma/rollup-plugin-off-main-thread": "^2.2.3", - "ajv": "^8.6.0", - "common-tags": "^1.8.0", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^9.0.1", - "glob": "^7.1.6", - "lodash": "^4.17.20", - "pretty-bytes": "^5.3.0", - "rollup": "^2.43.1", - "rollup-plugin-terser": "^7.0.0", - "source-map": "^0.8.0-beta.0", - "stringify-object": "^3.3.0", - "strip-comments": "^2.0.1", - "tempy": "^0.6.0", - "upath": "^1.2.0", - "workbox-background-sync": "6.5.3", - "workbox-broadcast-update": "6.5.3", - "workbox-cacheable-response": "6.5.3", - "workbox-core": "6.5.3", - "workbox-expiration": "6.5.3", - "workbox-google-analytics": "6.5.3", - "workbox-navigation-preload": "6.5.3", - "workbox-precaching": "6.5.3", - "workbox-range-requests": "6.5.3", - "workbox-recipes": "6.5.3", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3", - "workbox-streams": "6.5.3", - "workbox-sw": "6.5.3", - "workbox-window": "6.5.3" - }, - "dependencies": { - "@apideck/better-ajv-errors": { - "version": "0.3.4", - "requires": { - "json-schema": "^0.4.0", - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - } - }, - "ajv": { - "version": "8.11.0", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "fs-extra": { - "version": "9.1.0", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0" - }, - "source-map": { - "version": "0.8.0-beta.0", - "requires": { - "whatwg-url": "^7.0.0" - } - }, - "tr46": { - "version": "1.0.1", - "requires": { - "punycode": "^2.1.0" - } - }, - "webidl-conversions": { - "version": "4.0.2" - }, - "whatwg-url": { - "version": "7.1.0", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } - } - }, - "workbox-cacheable-response": { - "version": "6.5.3", - "requires": { - "workbox-core": "6.5.3" - } - }, - "workbox-core": { - "version": "6.5.3" - }, - "workbox-expiration": { - "version": "6.5.3", - "requires": { - "idb": "^6.1.4", - "workbox-core": "6.5.3" - } - }, - "workbox-google-analytics": { - "version": "6.5.3", - "requires": { - "workbox-background-sync": "6.5.3", - "workbox-core": "6.5.3", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3" - } - }, - "workbox-navigation-preload": { - "version": "6.5.3", - "requires": { - "workbox-core": "6.5.3" - } - }, - "workbox-precaching": { - "version": "6.5.3", - "requires": { - "workbox-core": "6.5.3", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3" - } - }, - "workbox-range-requests": { - "version": "6.5.3", - "requires": { - "workbox-core": "6.5.3" - } - }, - "workbox-recipes": { - "version": "6.5.3", - "requires": { - "workbox-cacheable-response": "6.5.3", - "workbox-core": "6.5.3", - "workbox-expiration": "6.5.3", - "workbox-precaching": "6.5.3", - "workbox-routing": "6.5.3", - "workbox-strategies": "6.5.3" - } - }, - "workbox-routing": { - "version": "6.5.3", - "requires": { - "workbox-core": "6.5.3" - } - }, - "workbox-strategies": { - "version": "6.5.3", - "requires": { - "workbox-core": "6.5.3" - } - }, - "workbox-streams": { - "version": "6.5.3", - "requires": { - "workbox-core": "6.5.3", - "workbox-routing": "6.5.3" - } - }, - "workbox-sw": { - "version": "6.5.3" - }, - "workbox-webpack-plugin": { - "version": "6.5.3", - "requires": { - "fast-json-stable-stringify": "^2.1.0", - "pretty-bytes": "^5.4.1", - "upath": "^1.2.0", - "webpack-sources": "^1.4.3", - "workbox-build": "6.5.3" - }, - "dependencies": { - "webpack-sources": { - "version": "1.4.3", - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - } - } - }, - "workbox-window": { - "version": "6.5.3", - "requires": { - "@types/trusted-types": "^2.0.2", - "workbox-core": "6.5.3" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4" - } - } - }, - "wrappy": { - "version": "1.0.2" - }, - "write-file-atomic": { - "version": "3.0.3", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.8", - "requires": {} - }, - "xml-name-validator": { - "version": "3.0.0" - }, - "xmlchars": { - "version": "2.2.0" - }, - "xtend": { - "version": "4.0.2" - }, - "y18n": { - "version": "5.0.8" - }, - "yallist": { - "version": "4.0.0" - }, - "yaml": { - "version": "1.10.2" - }, - "yargs": { - "version": "16.2.0", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9" - }, - "yocto-queue": { - "version": "0.1.0" - } } } diff --git a/bbb-learning-dashboard/package.json b/bbb-learning-dashboard/package.json index efc3ef2f1b..c58835f870 100644 --- a/bbb-learning-dashboard/package.json +++ b/bbb-learning-dashboard/package.json @@ -52,7 +52,7 @@ "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-react": "^7.24.0", "eslint-plugin-react-hooks": "^4.2.0", - "postcss": "^8.4.36", + "postcss": "^8.4.41", "tailwindcss": "^3.0.11" } } diff --git a/bbb-learning-dashboard/public/test/test/learning_dashboard_data.json b/bbb-learning-dashboard/public/test/test/learning_dashboard_data.json new file mode 100644 index 0000000000..2eaddc1d74 --- /dev/null +++ b/bbb-learning-dashboard/public/test/test/learning_dashboard_data.json @@ -0,0 +1 @@ +{"intId":"33f06e373c9e5f02f3e3acc51a339b618fb82a27-1720124768778","extId":"random-5359088","name":"random-5359088","downloadSessionDataEnabled":true,"users":{"w_odwvcjqtkurt-1":{"userKey":"w_odwvcjqtkurt-1","extId":"w_odwvcjqtkurt","intIds":{"w_odwvcjqtkurt":{"intId":"w_odwvcjqtkurt","registeredOn":1720124772784,"leftOn":0,"userLeftFlag":false}},"name":"User 6660498","isModerator":true,"isDialIn":false,"currentIntId":"w_odwvcjqtkurt","answers":{},"plugins":[],"talk":{"totalTime":0,"lastTalkStartedOn":0},"emojis":[],"reactions":[],"webcams":[],"totalOfMessages":0},"w_fcyakrglbqcm-1":{"userKey":"w_fcyakrglbqcm-1","extId":"w_fcyakrglbqcm","intIds":{"w_fcyakrglbqcm":{"intId":"w_fcyakrglbqcm","registeredOn":1720124772871,"leftOn":0,"userLeftFlag":false}},"name":"User 6660498","isModerator":true,"isDialIn":false,"currentIntId":"w_fcyakrglbqcm","answers":{},"plugins":[{"pluginName":"H5pPlugin","genericDataForLearningAnalyticsDashboard":{"cardTitle":"H5P","columnTitle":"Programmingexam","value":"2 / 10"}}],"talk":{"totalTime":0,"lastTalkStartedOn":0},"emojis":[],"reactions":[],"webcams":[],"totalOfMessages":0}},"polls":{},"screenshares":[],"presentationSlides":[{"presentationId":"b7b592bbdd7e32067aca2acd0797d41163d6ee0d-1720124768779","pageNum":1,"setOn":1720124774482,"presentationName":"default.pdf"},{"presentationId":"b7b592bbdd7e32067aca2acd0797d41163d6ee0d-1720124768779","pageNum":2,"setOn":1720124779872,"presentationName":"default.pdf"}],"createdOn":1720124768901,"endedOn":0} \ No newline at end of file diff --git a/bbb-learning-dashboard/src/App.js b/bbb-learning-dashboard/src/App.js index 6c055860a4..fb26182df4 100644 --- a/bbb-learning-dashboard/src/App.js +++ b/bbb-learning-dashboard/src/App.js @@ -6,17 +6,16 @@ import TabsListUnstyled from '@mui/base/TabsListUnstyled'; import TabPanelUnstyled from '@mui/base/TabPanelUnstyled'; import TabsUnstyled from '@mui/base/TabsUnstyled'; import './App.css'; -import './bbb-icons.css'; import { FormattedMessage, FormattedDate, injectIntl, FormattedTime, } from 'react-intl'; -import { emojiConfigs } from './services/EmojiService'; import CardBody from './components/Card'; import UsersTable from './components/UsersTable'; import UserDetails from './components/UserDetails/component'; import { UserDetailsContext } from './components/UserDetails/context'; import StatusTable from './components/StatusTable'; import PollsTable from './components/PollsTable'; +import PluginsTable from './components/PluginsTable'; import ErrorMessage from './components/ErrorMessage'; import { makeUserCSVData, tsToHHmmss } from './services/UserService'; @@ -124,38 +123,31 @@ class App extends React.Component { }); } - fetchMostUsedEmojis() { + fetchMostUsedReactions() { const { activitiesJson } = this.state; if (!activitiesJson) { return []; } - // Icon elements - const emojis = [...Object.keys(emojiConfigs)]; - const icons = {}; - emojis.forEach((emoji) => { - icons[emoji] = (); - }); - - // Count each emoji - const emojiCount = {}; - emojis.forEach((emoji) => { - emojiCount[emoji] = 0; - }); - const allEmojisUsed = Object + // Count each reaction + const reactionCount = {}; + const allReactionsUsed = Object .values(activitiesJson.users || {}) - .map((user) => user.emojis || []) + .map((user) => user.reactions || []) .flat(1); - allEmojisUsed.forEach((emoji) => { - emojiCount[emoji.name] += 1; + allReactionsUsed.forEach((reaction) => { + if (typeof reactionCount[reaction.name] === 'undefined') { + reactionCount[reaction.name] = 0; + } + reactionCount[reaction.name] += 1; }); // Get the three most used - const mostUsedEmojis = Object - .entries(emojiCount) + const mostUsedReactions = Object + .entries(reactionCount) .filter(([, count]) => count) .sort(([, countA], [, countB]) => countA - countB) .reverse() .slice(0, 3); - return mostUsedEmojis.map(([emoji]) => icons[emoji]); + return mostUsedReactions.map(([reaction]) => reaction); } updateModalUser() { @@ -229,12 +221,28 @@ class App extends React.Component { } = this.state; const { intl } = this.props; + const genericDataCardTitle = activitiesJson?.genericDataTitles?.[0]; + // This line generates an array of all the plugin entries of all users, + // this might have duplicate entries: + const genericDataColumnTitleWithDuplicates = Object.values( + activitiesJson.users || {}, // Hardcoded for now, we will add cards relative to this key. + ).flatMap(( + user, + ) => user.genericData?.[genericDataCardTitle]).filter(( + genericDataListForSpecificUser, + ) => !!( + genericDataListForSpecificUser?.columnTitle)).map(( + genericDataListForSpecificUser, + ) => genericDataListForSpecificUser?.columnTitle); + // This line will eliminate duplicates. + const genericDataColumnTitleList = [...new Set(genericDataColumnTitleWithDuplicates)]; + document.title = `${intl.formatMessage({ id: 'app.learningDashboard.bigbluebuttonTitle', defaultMessage: 'BigBlueButton' })} - ${intl.formatMessage({ id: 'app.learningDashboard.dashboardTitle', defaultMessage: 'Learning Analytics Dashboard' })} - ${activitiesJson.name}`; - function totalOfEmojis() { + function totalOfReactions() { if (activitiesJson && activitiesJson.users) { return Object.values(activitiesJson.users) - .reduce((prevVal, elem) => prevVal + elem.emojis.length, 0); + .reduce((prevVal, elem) => prevVal + elem.reactions.length, 0); } return 0; } @@ -285,19 +293,19 @@ class App extends React.Component { } // Calculate points of Raise hand - const usersRaiseHand = allUsers.map((currUser) => currUser.emojis.filter((emoji) => emoji.name === 'raiseHand').length); + const usersRaiseHand = allUsers.map((currUser) => currUser.raiseHand.length); const maxRaiseHand = Math.max(...usersRaiseHand); const totalRaiseHand = usersRaiseHand.reduce((prev, val) => prev + val, 0); if (maxRaiseHand > 0) { meetingAveragePoints += ((totalRaiseHand / nrOfUsers) / maxRaiseHand) * 2; } - // Calculate points of Emojis - const usersEmojis = allUsers.map((currUser) => currUser.emojis.filter((emoji) => emoji.name !== 'raiseHand').length); - const maxEmojis = Math.max(...usersEmojis); - const totalEmojis = usersEmojis.reduce((prev, val) => prev + val, 0); - if (maxEmojis > 0) { - meetingAveragePoints += ((totalEmojis / nrOfUsers) / maxEmojis) * 2; + // Calculate points of Reactions + const usersReactions = allUsers.map((currUser) => currUser.reactions.length); + const maxReactions = Math.max(...usersReactions); + const totalReactions = usersReactions.reduce((prev, val) => prev + val, 0); + if (maxReactions > 0) { + meetingAveragePoints += ((totalReactions / nrOfUsers) / maxReactions) * 2; } // Calculate points of Polls @@ -464,11 +472,11 @@ class App extends React.Component { - {this.fetchMostUsedEmojis()} + {this.fetchMostUsedReactions()} @@ -500,6 +508,35 @@ class App extends React.Component { + {genericDataColumnTitleList.length && ( + + + + + + + + + + + + )}

@@ -555,6 +592,20 @@ class App extends React.Component {

+ +

+ {genericDataCardTitle} +

+
+
+ +
+
+

diff --git a/bbb-learning-dashboard/src/bbb-icons.css b/bbb-learning-dashboard/src/bbb-icons.css deleted file mode 100755 index fd2e1a725f..0000000000 --- a/bbb-learning-dashboard/src/bbb-icons.css +++ /dev/null @@ -1,330 +0,0 @@ -@font-face { - font-family: 'bbb-icons'; - src: url('./fonts/BbbIcons/bbb-icons.woff') format('woff'); - font-weight: normal; - font-style: normal; -} - -[class^="icon-bbb-"], [class*=" icon-bbb-"] { - /* use !important to prevent issues with browser extensions that change fonts */ - font-family: 'bbb-icons', sans-serif !important; - speak: none; - position: relative; - /*top: 1px;*/ - display: inline-block; - font-style: normal; - font-weight: 400; - line-height: 1; - width: 1em; - text-align: center; - vertical-align: middle; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.bbb-icon-card { - font-size: 1.25rem; - font-weight: bold; -} - -.bbb-icon-timeline { - font-weight: bold; -} - -.icon-bbb-screenshare-fullscreen:before { - content: "\e92a"; -} -.icon-bbb-screenshare-close-fullscreen:before { - content: "\e935"; -} -.icon-bbb-alert:before { - content: "\e958"; -} -.icon-bbb-mute:before { - content: "\e932"; -} -.icon-bbb-unmute:before { - content: "\e931"; -} -.icon-bbb-file:before { - content: "\e92e"; -} -.icon-bbb-upload:before { - content: "\e92f"; -} -.icon-bbb-fullscreen:before { - content: "\e92a"; -} -.icon-bbb-exit_fullscreen:before { - content: "\e935"; -} -.icon-bbb-settings:before { - content: "\e92b"; -} -.icon-bbb-fit_to_screen:before { - content: "\e929"; -} -.icon-bbb-line_tool:before { - content: "\e91c"; -} -.icon-bbb-circle_tool:before { - content: "\e91d"; -} -.icon-bbb-triangle_tool:before { - content: "\e91e"; -} -.icon-bbb-rectangle_tool:before { - content: "\e91f"; -} -.icon-bbb-text_tool:before { - content: "\e920"; -} -.icon-bbb-plus:before { - content: "\e921"; -} -.icon-bbb-fit_to_width:before { - content: "\e922"; -} -.icon-bbb-undo:before { - content: "\e924"; -} -.icon-bbb-pen_tool:before { - content: "\e925"; -} -.icon-bbb-lock:before { - content: "\e926"; -} -.icon-bbb-polling:before { - content: "\e927"; -} -.icon-bbb-desktop:before { - content: "\e928"; -} -.icon-bbb-logout:before { - content: "\e900"; -} -.icon-bbb-video:before { - content: "\e930"; -} -.icon-bbb-elipsis:before { - content: "\e902"; -} -.icon-bbb-more:before { - content: "\e902"; - display: inline-block; - transform: rotate(90deg); -} -.icon-bbb-promote:before { - content: "\e903"; -} -.icon-bbb-application:before { - content: "\e901"; -} -.icon-bbb-video_off:before { - content: "\e904"; -} -.icon-bbb-user:before { - content: "\e905"; -} -.icon-bbb-up_arrow:before { - content: "\e906"; -} -.icon-bbb-right_arrow:before { - content: "\e90a"; -} -.icon-bbb-presentation:before { - content: "\e90b"; -} -.icon-bbb-listen:before { - content: "\e90c"; -} -.icon-bbb-left_arrow:before { - content: "\e90d"; -} -.icon-bbb-group_chat:before { - content: "\e910"; -} -.icon-bbb-close:before { - content: "\e912"; -} -.icon-bbb-clear_status:before { - content: "\e913"; -} -.icon-bbb-circle:before { - content: "\e914"; -} -.icon-bbb-substract:before { - content: "\e915"; -} -.icon-bbb-circle_close:before { - content: "\e916"; -} -.icon-bbb-add:before { - content: "\e917"; -} -.icon-bbb-check:before { - content: "\e918"; -} -.icon-bbb-chat:before { - content: "\e919"; -} -.icon-bbb-audio_on:before { - content: "\e91a"; -} -.icon-bbb-audio_off:before { - content: "\e91b"; -} - -.icon-bbb-volume_down:before { - content: "\e947"; -} - -.icon-bbb-volume_mute:before { - content: "\e947"; -} - -.icon-bbb-volume_off:before { - content: "\e947"; -} - -.icon-bbb-volume_up:before { - content: "\e947"; -} - -/* Aliases for emoji status */ -.icon-bbb-time:before { - content: "\e908"; -} -.icon-bbb-hand:before { - content: "\e90f"; -} -.icon-bbb-undecided:before { - content: "\e907"; -} -.icon-bbb-happy:before { - content: "\e90e"; -} -.icon-bbb-sad:before { - content: "\e909"; -} -.icon-bbb-confused:before { - content: "\e911"; -} -.icon-bbb-applause:before { - content: "\e923"; -} -.icon-bbb-thumbs_up:before { - content: "\e92d"; -} -.icon-bbb-thumbs_down:before { - content: "\e92c"; -} -.icon-bbb-send:before { - content: "\e934"; -} -.icon-bbb-about:before { - content: "\e933"; -} - -.icon-bbb-delete:before { - content: "\e936"; -} -.icon-bbb-unmute_filled:before { - content: "\e937"; -} -.icon-bbb-mute_filled:before { - content: "\e938"; -} -.icon-bbb-listen_filled:before { - content: "\e939"; -} -.icon-bbb-template_upload:before { - content: "\e93a"; -} -.icon-bbb-template_download:before { - content: "\e93b"; -} -.icon-bbb-download:before { - content: "\e93c"; -} -.icon-bbb-multi_whiteboard:before { - content: "\e93d"; -} -.icon-bbb-whiteboard:before { - content: "\e93e"; -} -.icon-bbb-rooms:before { - content: "\e93f"; -} -.icon-bbb-unlock:before { - content: "\e940"; -} -.icon-bbb-record:before { - content: "\e941"; -} -.icon-bbb-network:before { - content: "\e942"; -} -.icon-bbb-redo:before { - content: "\e943"; -} -.icon-bbb-thumbs_down_filled:before { - content: "\e944"; -} -.icon-bbb-thumbs_up_filled:before { - content: "\e945"; -} -.icon-bbb-checkmark:before { - content: "\e946"; -} -.icon-bbb-speak_louder:before { - content: "\e947"; -} -.icon-bbb-help:before { - content: "\e948"; -} -.icon-bbb-refresh:before { - content: "\e949"; -} -.icon-bbb-copy:before { - content: "\e94a"; -} -.icon-bbb-shortcuts:before { - content: "\e94b"; -} -.icon-bbb-warning:before { - content: "\e94c"; -} -.icon-bbb-pointer:before { - content: "\e950"; -} -.icon-bbb-star_filled:before { - content: "\e952"; -} -.icon-bbb-desktop_off:before { - content: "\e953"; -} -.icon-bbb-minus:before { - content: "\e954"; -} -.icon-bbb-download-off:before { - content: "\e955"; -} -.icon-bbb-popout_window:before { - content: "\e956"; -} -.icon-bbb-closed_caption:before { - content: "\e957"; -} -/*\e958 -> icon-bbb-alert*/ -.icon-bbb-palm_rejection:before { - content: "\e959"; -} -.icon-bbb-no_palm_rejection:before { - content: "\e95a"; -} -.icon-bbb-device_list_selector:before { - content: "\e95b"; -} diff --git a/bbb-learning-dashboard/src/components/PluginsTable.jsx b/bbb-learning-dashboard/src/components/PluginsTable.jsx new file mode 100644 index 0000000000..6e27bf4bb1 --- /dev/null +++ b/bbb-learning-dashboard/src/components/PluginsTable.jsx @@ -0,0 +1,128 @@ +import React from 'react'; +import { injectIntl } from 'react-intl'; +import { DataGrid } from '@mui/x-data-grid'; +import UserAvatar from './UserAvatar'; + +// Type of genericData is of the form: { +// columnTitle: string; +// value: string +// } +const PluginsTable = (props) => { + const { + genericDataColumnTitleList, + allUsers, intl, genericDataCardTitle, + } = props; + + const commonUserProps = { + field: 'User', + headerName: intl.formatMessage({ id: 'app.learningDashboard.pluginsTable.userLabel', defaultMessage: 'User' }), + flex: 1, + sortable: true, + }; + + const commonCountProps = { + field: 'count', + headerName: intl.formatMessage({ id: 'app.learningDashboard.pluginsTable.totalLabel', defaultMessage: 'Total' }), + flex: 1, + sortable: true, + }; + + const gridCols = [ + { + ...commonUserProps, + valueGetter: (params) => params?.row?.User?.name, + renderCell: (params) => ( + <> +
+ +
+
{params?.value}
+ + ), + }, + ]; + + gridCols.push({ + ...commonCountProps, + valueGetter: (params) => Object.keys( + params?.row?.User?.genericData?.[genericDataCardTitle], + )?.length || 0, + renderCell: (params) => params?.value, + }); + + genericDataColumnTitleList.map((pluginColumnTitle) => { + const commonColProps = { + field: pluginColumnTitle, + headerName: pluginColumnTitle, + flex: 1, + }; + gridCols.push({ + ...commonColProps, + valueGetter: ( + params, + ) => params?.row?.[pluginColumnTitle], + renderCell: (params) => params?.value, + }); + return pluginColumnTitle; + }); + + const gridRows = []; + Object.values(allUsers).map((u, i) => { + if (Object.keys(u?.genericData)?.length === 0) return u; + gridRows.push({ + id: i + 1, + User: u, + // This is going to be of the form: + // [learningAnalyticsDashboardColumnTitle]: learningAnalyticsDashboardValue, for each entry + ...u.genericData?.[genericDataCardTitle].reduce((acc, curr) => { + const { + columnTitle, + value, + } = curr; + acc[columnTitle] = value; + return acc; + }, {}), + }); + return u; + }); + + const commonGridProps = { + autoHeight: true, + hideFooter: true, + disableColumnMenu: true, + disableColumnSelector: true, + disableSelectionOnClick: true, + rowHeight: 45, + }; + + return ( +
+ +
+ ); +}; + +export default injectIntl(PluginsTable); diff --git a/bbb-learning-dashboard/src/components/StatusTable.jsx b/bbb-learning-dashboard/src/components/StatusTable.jsx index 50c7faa0bc..56c19cf813 100644 --- a/bbb-learning-dashboard/src/components/StatusTable.jsx +++ b/bbb-learning-dashboard/src/components/StatusTable.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; -import { emojiConfigs, filterUserEmojis } from '../services/EmojiService'; +import { filterUserReactions } from '../services/ReactionService'; import UserAvatar from './UserAvatar'; const intlMessages = defineMessages({ @@ -24,31 +24,31 @@ const intlMessages = defineMessages({ class StatusTable extends React.Component { componentDidMount() { - // This code is needed to prevent emojis from overflowing. - const emojis = document.getElementsByClassName('timeline-emoji'); - for (let i = 0; i < emojis.length; i += 1) { - const emojiStyle = window.getComputedStyle(emojis[i]); - const offsetLeft = Number(emojiStyle + // This code is needed to prevent reactions from overflowing. + const reactions = document.getElementsByClassName('timeline-reaction'); + for (let i = 0; i < reactions.length; i += 1) { + const reactionStyle = window.getComputedStyle(reactions[i]); + const offsetLeft = Number(reactionStyle .left .replace(/px/g, '') .trim()); if (offsetLeft < 0) { - emojis[i].style.left = '0'; + reactions[i].style.left = '0'; } } } componentDidUpdate() { - // This code is needed to prevent emojis from overflowing. - const emojis = document.getElementsByClassName('timeline-emoji'); - for (let i = 0; i < emojis.length; i += 1) { - const emojiStyle = window.getComputedStyle(emojis[i]); - const offsetLeft = Number(emojiStyle + // This code is needed to prevent reactions from overflowing. + const reactions = document.getElementsByClassName('timeline-reaction'); + for (let i = 0; i < reactions.length; i += 1) { + const reactionStyle = window.getComputedStyle(reactions[i]); + const offsetLeft = Number(reactionStyle .left .replace(/px/g, '') .trim()); if (offsetLeft < 0) { - emojis[i].style.left = '0'; + reactions[i].style.left = '0'; } } } @@ -287,8 +287,7 @@ class StatusTable extends React.Component { { usersPeriods[user.userKey].length > 0 ? ( usersPeriods[user.userKey].map((userPeriod) => { const { registeredOn, leftOn } = userPeriod; - const userEmojisInPeriod = filterUserEmojis(user, - null, + const userReactionsInPeriod = filterUserReactions(user, registeredOn >= boundaryLeft && registeredOn <= boundaryRight ? registeredOn : boundaryLeft, leftOn >= boundaryLeft && leftOn <= boundaryRight @@ -301,34 +300,21 @@ class StatusTable extends React.Component { || (boundaryLeft >= registeredOn && leftOn === 0) ? makeLineThrough(userPeriod, period) : null } - { userEmojisInPeriod.map((emoji) => { - const offset = ((emoji.sentOn - period.start) * 100) + { userReactionsInPeriod.map((reaction) => { + const offset = ((reaction.sentOn - period.start) * 100) / (interval); const origin = isRTL ? 'right' : 'left'; const redress = '(0.875rem / 2 + 0.25rem + 2px)'; return (
- + {reaction.name}
); }) } diff --git a/bbb-learning-dashboard/src/components/UserDetails/component.jsx b/bbb-learning-dashboard/src/components/UserDetails/component.jsx index 31b27f5b4e..73c181325f 100644 --- a/bbb-learning-dashboard/src/components/UserDetails/component.jsx +++ b/bbb-learning-dashboard/src/components/UserDetails/component.jsx @@ -57,12 +57,12 @@ const UserDatailsComponent = (props) => { const leftTimes = Object.values(user.intIds).map((intId) => intId.leftOn); const joinTime = Math.min(...registeredTimes); const leftTime = Math.max(...leftTimes); - const isOnline = Object.values(user.intIds).some((intId) => intId.leftOn === 0); + const currentlyInMeeting = Object.values(user.intIds).some((intId) => intId.leftOn === 0); // Used in the calculation of the online loader. const sessionDuration = (endedOn || currTime()) - createdOn; const userStartOffsetTime = ((joinTime - createdOn) * 100) / sessionDuration; - const userEndOffsetTime = isOnline + const userEndOffsetTime = currentlyInMeeting ? 0 : (((endedOn || currTime()) - leftTime) * 100) / sessionDuration; @@ -109,8 +109,8 @@ const UserDatailsComponent = (props) => { const usersTalkTime = allUsersArr.map((currUser) => currUser.talk.totalTime); const usersMessages = allUsersArr.map((currUser) => currUser.totalOfMessages); - const usersEmojis = allUsersArr.map((currUser) => currUser.emojis.filter((emoji) => emoji.name !== 'raiseHand').length); - const usersRaiseHands = allUsersArr.map((currUser) => currUser.emojis.filter((emoji) => emoji.name === 'raiseHand').length); + const usersReactions = allUsersArr.map((currUser) => currUser.reactions.length); + const usersRaiseHands = allUsersArr.map((currUser) => currUser.raiseHand.length); const usersAnswers = allUsersArr.map((currUser) => Object.values(currUser.answers || {}).length); const totalPolls = Object.values(polls || {}).length; @@ -132,18 +132,18 @@ const UserDatailsComponent = (props) => { function getPointsOfRaiseHand(u) { const maxRaiseHand = Math.max(...usersRaiseHands); - const userRaiseHand = u.emojis.filter((emoji) => emoji.name === 'raiseHand').length; + const userRaiseHand = u.reactions.length; if (maxRaiseHand > 0) { return (userRaiseHand / maxRaiseHand) * 2; } return 0; } - function getPointsofEmoji(u) { - const maxEmojis = Math.max(...usersEmojis); - const userEmojis = u.emojis.filter((emoji) => emoji.name !== 'raiseHand').length; - if (maxEmojis > 0) { - return (userEmojis / maxEmojis) * 2; + function getPointsofReaction(u) { + const maxReactions = Math.max(...usersReactions); + const userReactions = u.reactions.length; + if (maxReactions > 0) { + return (userReactions / maxReactions) * 2; } return 0; } @@ -161,7 +161,7 @@ const UserDatailsComponent = (props) => { const messagesAverage = usersMessages .reduce((prev, curr) => prev + curr, 0) / (allUsersArr.length || 1); - const emojisAverage = usersEmojis + const reactionsAverage = usersReactions .reduce((prev, curr) => prev + curr, 0) / (allUsersArr.length || 1); const raiseHandsAverage = usersRaiseHands @@ -173,7 +173,7 @@ const UserDatailsComponent = (props) => { const activityPointsFunctions = { 'Talk Time': getPointsOfTalk, Messages: getPointsOfChatting, - Emojis: getPointsofEmoji, + Reactions: getPointsofReaction, 'Raise Hands': getPointsOfRaiseHand, 'Poll Votes': getPointsOfPolls, }; @@ -181,7 +181,7 @@ const UserDatailsComponent = (props) => { const averages = { 'Talk Time': talkTimeAverage, Messages: messagesAverage, - Emojis: emojisAverage, + Reactions: reactionsAverage, 'Raise Hands': raiseHandsAverage, 'Poll Votes': pollsAverage, }; @@ -400,7 +400,7 @@ const UserDatailsComponent = (props) => {
- { isOnline ? ( + { currentlyInMeeting ? ( @@ -436,7 +436,7 @@ const UserDatailsComponent = (props) => { - { ['Talk Time', 'Messages', 'Emojis', 'Raise Hands', 'Poll Votes'].map((category) => { + { ['Talk Time', 'Messages', 'Reactions', 'Raise Hands', 'Poll Votes'].map((category) => { let totalOfActivity = 0; switch (category) { @@ -446,11 +446,11 @@ const UserDatailsComponent = (props) => { case 'Messages': totalOfActivity = user.totalOfMessages; break; - case 'Emojis': - totalOfActivity = user.emojis.filter((emoji) => emoji.name !== 'raiseHand').length; + case 'Reactions': + totalOfActivity = user.reactions.length; break; case 'Raise Hands': - totalOfActivity = user.emojis.filter((emoji) => emoji.name === 'raiseHand').length; + totalOfActivity = user.raiseHand.length; break; case 'Poll Votes': totalOfActivity = Object.values(user.answers).length; diff --git a/bbb-learning-dashboard/src/components/UsersTable.jsx b/bbb-learning-dashboard/src/components/UsersTable.jsx index f10dd13765..e98b9a8f84 100644 --- a/bbb-learning-dashboard/src/components/UsersTable.jsx +++ b/bbb-learning-dashboard/src/components/UsersTable.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { FormattedMessage, FormattedDate, FormattedNumber, injectIntl, } from 'react-intl'; -import { getUserEmojisSummary, emojiConfigs } from '../services/EmojiService'; +import { getUserReactionsSummary } from '../services/ReactionService'; import { getActivityScore, getSumOfTime, tsToHHmmss } from '../services/UserService'; import UserAvatar from './UserAvatar'; import { UserDetailsContext } from './UserDetails/context'; @@ -73,9 +73,9 @@ class UsersTable extends React.Component { talkTimeOrder, webcamTimeOrder, lastFieldClicked, } = this.state; - const usersEmojisSummary = {}; + const usersReactionsSummary = {}; Object.values(allUsers || {}).forEach((user) => { - usersEmojisSummary[user.userKey] = getUserEmojisSummary(user, 'raiseHand'); + usersReactionsSummary[user.userKey] = getUserReactionsSummary(user); }); function getOnlinePercentage(registeredOn, leftOn) { @@ -206,7 +206,7 @@ class UsersTable extends React.Component { - + @@ -429,42 +429,25 @@ class UsersTable extends React.Component { ) : null } - + { - Object.keys(usersEmojisSummary[user.userKey] || {}).map((emoji) => ( + Object.keys(usersReactionsSummary[user.userKey] || {}).map((reaction) => (
- + {reaction}   - { usersEmojisSummary[user.userKey][emoji] } + { usersReactionsSummary[user.userKey][reaction] }   -
)) } - { user.emojis.filter((emoji) => emoji.name === 'raiseHand').length > 0 + { user.raiseHand.length > 0 ? ( - - - + ✋   - {user.emojis.filter((emoji) => emoji.name === 'raiseHand').length} + {user.raiseHand.length} ) : null } diff --git a/bbb-learning-dashboard/src/services/EmojiService.js b/bbb-learning-dashboard/src/services/EmojiService.js deleted file mode 100644 index 20fdd737ce..0000000000 --- a/bbb-learning-dashboard/src/services/EmojiService.js +++ /dev/null @@ -1,74 +0,0 @@ -export const emojiConfigs = { - away: { - icon: 'icon-bbb-time', - intlId: 'app.actionsBar.emojiMenu.awayLabel', - defaultMessage: 'Away', - }, - neutral: { - icon: 'icon-bbb-undecided', - intlId: 'app.actionsBar.emojiMenu.neutralLabel', - defaultMessage: 'Undecided', - }, - confused: { - icon: 'icon-bbb-confused', - intlId: 'app.actionsBar.emojiMenu.confusedLabel', - defaultMessage: 'Confused', - }, - sad: { - icon: 'icon-bbb-sad', - intlId: 'app.actionsBar.emojiMenu.sadLabel', - defaultMessage: 'Sad', - }, - happy: { - icon: 'icon-bbb-happy', - intlId: 'app.actionsBar.emojiMenu.happyLabel', - defaultMessage: 'Happy', - }, - applause: { - icon: 'icon-bbb-applause', - intlId: 'app.actionsBar.emojiMenu.applauseLabel', - defaultMessage: 'Applaud', - }, - thumbsUp: { - icon: 'icon-bbb-thumbs_up', - intlId: 'app.actionsBar.emojiMenu.thumbsUpLabel', - defaultMessage: 'Thumbs up', - }, - thumbsDown: { - icon: 'icon-bbb-thumbs_down', - intlId: 'app.actionsBar.emojiMenu.thumbsDownLabel', - defaultMessage: 'Thumbs down', - }, - raiseHand: { - icon: 'icon-bbb-hand', - intlId: 'app.actionsBar.emojiMenu.raiseHandLabel', - defaultMessage: 'Raise hand', - }, -}; - -export function getUserEmojisSummary(user, skipNames = null, start = null, end = null) { - const userEmojis = {}; - user.emojis.forEach((emoji) => { - if (typeof emojiConfigs[emoji.name] === 'undefined') return; - if (skipNames != null && skipNames.split(',').indexOf(emoji.name) > -1) return; - if (start != null && emoji.sentOn < start) return; - if (end != null && emoji.sentOn > end) return; - if (typeof userEmojis[emoji.name] === 'undefined') { - userEmojis[emoji.name] = 0; - } - userEmojis[emoji.name] += 1; - }); - return userEmojis; -} - -export function filterUserEmojis(user, skipNames = null, start = null, end = null) { - const userEmojis = []; - user.emojis.forEach((emoji) => { - if (typeof emojiConfigs[emoji.name] === 'undefined') return; - if (skipNames != null && skipNames.split(',').indexOf(emoji.name) > -1) return; - if (start != null && emoji.sentOn < start) return; - if (end != null && emoji.sentOn > end) return; - userEmojis.push(emoji); - }); - return userEmojis; -} diff --git a/bbb-learning-dashboard/src/services/ReactionService.js b/bbb-learning-dashboard/src/services/ReactionService.js new file mode 100644 index 0000000000..cc9b077b86 --- /dev/null +++ b/bbb-learning-dashboard/src/services/ReactionService.js @@ -0,0 +1,20 @@ +export function getUserReactionsSummary(user) { + const userReactions = {}; + user.reactions.forEach((reaction) => { + if (typeof userReactions[reaction.name] === 'undefined') { + userReactions[reaction.name] = 0; + } + userReactions[reaction.name] += 1; + }); + return userReactions; +} + +export function filterUserReactions(user, start = null, end = null) { + const userReactions = []; + user.reactions.forEach((reaction) => { + if (start != null && reaction.sentOn < start) return; + if (end != null && reaction.sentOn > end) return; + userReactions.push(reaction); + }); + return userReactions; +} diff --git a/bbb-learning-dashboard/src/services/UserService.js b/bbb-learning-dashboard/src/services/UserService.js index f7a977de7c..516600820d 100644 --- a/bbb-learning-dashboard/src/services/UserService.js +++ b/bbb-learning-dashboard/src/services/UserService.js @@ -1,4 +1,4 @@ -import { emojiConfigs, filterUserEmojis } from './EmojiService'; +import { filterUserReactions } from './ReactionService'; export function getActivityScore(user, allUsers, totalOfPolls) { if (user.isModerator) return 0; @@ -21,19 +21,19 @@ export function getActivityScore(user, allUsers, totalOfPolls) { } // Calculate points of Raise hand - const usersRaiseHand = allUsersArr.map((currUser) => currUser.emojis.filter((emoji) => emoji.name === 'raiseHand').length); + const usersRaiseHand = allUsersArr.map((currUser) => currUser.raiseHand.length); const maxRaiseHand = Math.max(...usersRaiseHand); - const userRaiseHand = user.emojis.filter((emoji) => emoji.name === 'raiseHand').length; + const userRaiseHand = user.raiseHand.length; if (maxRaiseHand > 0) { userPoints += (userRaiseHand / maxRaiseHand) * 2; } - // Calculate points of Emojis - const usersEmojis = allUsersArr.map((currUser) => currUser.emojis.filter((emoji) => emoji.name !== 'raiseHand').length); - const maxEmojis = Math.max(...usersEmojis); - const userEmojis = user.emojis.filter((emoji) => emoji.name !== 'raiseHand').length; - if (maxEmojis > 0) { - userPoints += (userEmojis / maxEmojis) * 2; + // Calculate points of Reactions + const usersReactions = allUsersArr.map((currUser) => currUser.reactions.length); + const maxReactions = Math.max(...usersReactions); + const userReactions = user.reactions.length; + if (maxReactions > 0) { + userPoints += (userReactions / maxReactions) * 2; } // Calculate points of Polls @@ -101,8 +101,8 @@ const tableHeaderFields = [ defaultMessage: 'Messages', }, { - id: 'colEmojis', - defaultMessage: 'Emojis', + id: 'colReactions', + defaultMessage: 'Reactions', }, { id: 'pollVotes', @@ -130,10 +130,6 @@ export function makeUserCSVData(users, polls, intl) { const userRecords = {}; const userValues = Object.values(users || {}); const pollValues = Object.values(polls || {}); - const skipEmojis = Object - .keys(emojiConfigs) - .filter((emoji) => emoji !== 'raiseHand') - .join(','); for (let i = 0; i < userValues.length; i += 1) { const user = userValues[i]; @@ -155,9 +151,9 @@ export function makeUserCSVData(users, polls, intl) { talk: user.talk.totalTime > 0 ? tsToHHmmss(user.talk.totalTime) : '-', webcam: webcam > 0 ? tsToHHmmss(webcam) : '-', messages: user.totalOfMessages, - raiseHand: filterUserEmojis(user, 'raiseHand').length, + reactions: filterUserReactions(user).length, answers: Object.keys(user.answers).length, - emojis: filterUserEmojis(user, skipEmojis).length, + raiseHand: user.raiseHand.length, registeredOn: intl.formatDate(joinTime, { year: 'numeric', month: 'numeric', diff --git a/bbb-pads.placeholder.sh b/bbb-pads.placeholder.sh index 6d004e65c5..7e48eedcb2 100755 --- a/bbb-pads.placeholder.sh +++ b/bbb-pads.placeholder.sh @@ -1 +1 @@ -git clone --branch v1.5.2 --depth 1 https://github.com/bigbluebutton/bbb-pads bbb-pads +git clone --branch v1.5.3 --depth 1 https://github.com/bigbluebutton/bbb-pads bbb-pads diff --git a/bbb-playback.placeholder.sh b/bbb-playback.placeholder.sh index a6bee22576..7b01b9f96f 100755 --- a/bbb-playback.placeholder.sh +++ b/bbb-playback.placeholder.sh @@ -1 +1 @@ -git clone --branch v5.1.0 --depth 1 https://github.com/bigbluebutton/bbb-playback bbb-playback +git clone --branch v5.1.1 --depth 1 https://github.com/bigbluebutton/bbb-playback bbb-playback diff --git a/bbb-presentation-video.placeholder.sh b/bbb-presentation-video.placeholder.sh index 8285524966..afcea1ee16 100755 --- a/bbb-presentation-video.placeholder.sh +++ b/bbb-presentation-video.placeholder.sh @@ -1,6 +1,6 @@ #!/bin/sh set -ex -RELEASE=4.0.4 +RELEASE=5.0.0-beta.1 cat < - + + + + + + + + + diff --git a/bbb-voice-conference/config/freeswitch/conf/dialplan/public/bbb_sfu.xml b/bbb-voice-conference/config/freeswitch/conf/dialplan/public/bbb_sfu.xml index 7f6a6e08f4..00bd7ff61b 100644 --- a/bbb-voice-conference/config/freeswitch/conf/dialplan/public/bbb_sfu.xml +++ b/bbb-voice-conference/config/freeswitch/conf/dialplan/public/bbb_sfu.xml @@ -1,6 +1,6 @@ - + diff --git a/bbb-voice-conference/config/freeswitch/conf/dialplan/public/bbb_sfu_muted.xml b/bbb-voice-conference/config/freeswitch/conf/dialplan/public/bbb_sfu_muted.xml new file mode 100644 index 0000000000..c3586353f0 --- /dev/null +++ b/bbb-voice-conference/config/freeswitch/conf/dialplan/public/bbb_sfu_muted.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/bbb-webhooks.placeholder.sh b/bbb-webhooks.placeholder.sh index 697c27d9fd..52ca3e5df6 100755 --- a/bbb-webhooks.placeholder.sh +++ b/bbb-webhooks.placeholder.sh @@ -1 +1 @@ -git clone --branch v3.1.0 --depth 1 https://github.com/bigbluebutton/bbb-webhooks bbb-webhooks +git clone --branch v3.2.1 --depth 1 https://github.com/bigbluebutton/bbb-webhooks bbb-webhooks diff --git a/bbb-webrtc-sfu.placeholder.sh b/bbb-webrtc-sfu.placeholder.sh index 200694fb12..77883d3abb 100755 --- a/bbb-webrtc-sfu.placeholder.sh +++ b/bbb-webrtc-sfu.placeholder.sh @@ -1 +1 @@ -git clone --branch v2.14.0-beta.0 --depth 1 https://github.com/bigbluebutton/bbb-webrtc-sfu bbb-webrtc-sfu +git clone --branch v2.15.0-beta.0 --depth 1 https://github.com/bigbluebutton/bbb-webrtc-sfu bbb-webrtc-sfu diff --git a/bigbluebutton-config/bigbluebutton-release b/bigbluebutton-config/bigbluebutton-release index 36ab6f49c1..5bbaefbd45 100644 --- a/bigbluebutton-config/bigbluebutton-release +++ b/bigbluebutton-config/bigbluebutton-release @@ -1 +1 @@ -BIGBLUEBUTTON_RELEASE=3.0.0-alpha.6 +BIGBLUEBUTTON_RELEASE=3.0.0-beta.1 diff --git a/bigbluebutton-config/bin/apply-lib.sh b/bigbluebutton-config/bin/apply-lib.sh index 1bb2b11c24..5786d62e31 100644 --- a/bigbluebutton-config/bin/apply-lib.sh +++ b/bigbluebutton-config/bin/apply-lib.sh @@ -58,7 +58,6 @@ enableHTML5ClientLog() { yq e -i '.public.clientLog.external.enabled = true' $HTML5_CONFIG yq e -i ".public.clientLog.external.url = \"$PROTOCOL://$HOST/html5log\"" $HTML5_CONFIG yq e -i '.public.app.askForFeedbackOnLogout = true' $HTML5_CONFIG - chown meteor:meteor $HTML5_CONFIG cat > /usr/share/bigbluebutton/nginx/html5-client-log.nginx << HERE location /html5log { diff --git a/bigbluebutton-config/bin/bbb-conf b/bigbluebutton-config/bin/bbb-conf index 08fba3230c..030adbcd90 100755 --- a/bigbluebutton-config/bin/bbb-conf +++ b/bigbluebutton-config/bin/bbb-conf @@ -147,24 +147,24 @@ RECORD_CONFIG=/usr/local/bigbluebutton/core/scripts/bigbluebutton.yml WEBRTC_RECORDER_DEFAULT_CONFIG=/etc/bbb-webrtc-recorder/bbb-webrtc-recorder.yml WEBRTC_RECORDER_ETC_CONFIG=/etc/bigbluebutton/bbb-webrtc-recorder.yml if [ -f $WEBRTC_RECORDER_ETC_CONFIG ]; then - WEBRTC_RECORDER_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $WEBRTC_RECORDER_DEFAULT_CONFIG $WEBRTC_RECORDER_ETC_CONFIG > /dev/null) + WEBRTC_RECORDER_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $WEBRTC_RECORDER_DEFAULT_CONFIG $WEBRTC_RECORDER_ETC_CONFIG 2> /dev/null) else - WEBRTC_RECORDER_CONFIG=$(yq e $WEBRTC_RECORDER_DEFAULT_CONFIG > /dev/null) + WEBRTC_RECORDER_CONFIG=$(yq e $WEBRTC_RECORDER_DEFAULT_CONFIG 2> /dev/null) fi -HTML5_DEFAULT_CONFIG=/usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml +HTML5_DEFAULT_CONFIG=/var/bigbluebutton/html5-client/private/config/settings.yml HTML5_ETC_CONFIG=/etc/bigbluebutton/bbb-html5.yml if [ -f $HTML5_ETC_CONFIG ]; then - HTML5_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $HTML5_DEFAULT_CONFIG $HTML5_ETC_CONFIG > /dev/null) + HTML5_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $HTML5_DEFAULT_CONFIG $HTML5_ETC_CONFIG 2> /dev/null) else - HTML5_CONFIG=$(yq e $HTML5_DEFAULT_CONFIG > /dev/null) + HTML5_CONFIG=$(yq e $HTML5_DEFAULT_CONFIG 2> /dev/null) fi mkdir -p /etc/bigbluebutton/bbb-webrtc-sfu WEBRTC_SFU_DEFAULT_CONFIG=/usr/local/bigbluebutton/bbb-webrtc-sfu/config/default.yml WEBRTC_SFU_ETC_CONFIG=/etc/bigbluebutton/bbb-webrtc-sfu/production.yml touch $WEBRTC_SFU_ETC_CONFIG # create it as it gets modified later in this script -WEBRTC_SFU_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $WEBRTC_SFU_DEFAULT_CONFIG $WEBRTC_SFU_ETC_CONFIG > /dev/null) +WEBRTC_SFU_CONFIG=$(yq eval-all '. as $item ireduce ({}; . * $item )' $WEBRTC_SFU_DEFAULT_CONFIG $WEBRTC_SFU_ETC_CONFIG 2> /dev/null) BBB_WEB_CONFIG="$SERVLET_DIR/WEB-INF/classes/bigbluebutton.properties" BBB_WEB_ETC_CONFIG="/etc/bigbluebutton/bbb-web.properties" @@ -367,21 +367,11 @@ start_bigbluebutton () { echo "Starting BigBlueButton" systemctl restart bigbluebutton.target - - if [ -f /usr/lib/systemd/system/bbb-html5.service ]; then - systemctl start mongod - sleep 3 - systemctl start bbb-html5 - fi } display_bigbluebutton_status () { units="nginx freeswitch $REDIS_SERVICE bbb-apps-akka bbb-fsesl-akka" - if [ -f /usr/lib/systemd/system/bbb-html5.service ]; then - units="$units mongod bbb-html5" - fi - if [ -f /usr/lib/systemd/system/bbb-graphql-actions.service ]; then units="$units bbb-graphql-actions" fi @@ -740,10 +730,10 @@ check_configuration() { fi fi - SIP_PROTOCOL=$(cat /usr/share/bigbluebutton/nginx/sip.nginx | grep -v \# | sed -n '/proxy_pass/{s/.*proxy_pass [ ]*//;s/:.*//;p}' | head -n 1) + SIP_PROTOCOL=$(cat "$SIP_CONFIG" | grep -v \# | sed -n '/proxy_pass/{s/.*proxy_pass [ ]*//;s/:.*//;p}' | head -n 1) if [[ $SIP_PROTOCOL == "https" ]]; then if ! grep wss-binding $FREESWITCH_EXTERNAL > /dev/null; then - echo "# Warning: Websockets is using HTTPS in /usr/share/bigbluebutton/nginx/sip.nginx" + echo "# Warning: Websockets is using HTTPS in $SIP_CONFIG" echo "# but no definition for wss-binding found in " echo "#" echo "# $FREESWITCH_EXTERNAL" @@ -1031,7 +1021,7 @@ check_state() { if [ "$SIP_NGINX_IP" != "\$freeswitch_addr" ]; then echo "# Warning: The setting of $SIP_NGINX_IP for proxy_pass in" echo "#" - echo "# /usr/share/bigbluebutton/nginx/sip.nginx" + echo "# $SIP_CONFIG" echo "#" echo "# does not match the local IP address ($IP)." echo "# (This is OK if you've manually changed the values)" @@ -1203,6 +1193,16 @@ check_state() { echo "#" fi + # check for any maintainer configuration files being ignored + dpkg_dist_files=$(find /etc/default -type f -name "*.dpkg-dist") + if [ -n "$dpkg_dist_files" ]; then + echo "# Warning: found the following configuration files which were ignored when installing." + echo "# Please inspect those files and consider applying the differences to the similarly" + echo "# named configuration file in the same directory." + echo "# When done, please restart BigBlueButton." + echo "#" + echo "$dpkg_dist_files" + fi exit 0 } @@ -1288,7 +1288,7 @@ if [ $CHECK ]; then echo echo "$SIP_CONFIG (sip.nginx)" echo " proxy_pass: $SIP_NGINX_IP" - echo " protocol: $(cat /usr/share/bigbluebutton/nginx/sip.nginx | grep -v \# | sed -n '/proxy_pass/{s/.*proxy_pass [ ]*//;s/:.*//;p}' | head -n 1)" + echo " protocol: $(cat "$SIP_CONFIG" | grep -v \# | sed -n '/proxy_pass/{s/.*proxy_pass [ ]*//;s/:.*//;p}' | head -n 1)" fi if [ -n "$WEBRTC_SFU_CONFIG" ]; then @@ -1318,7 +1318,7 @@ if [ $CHECK ]; then if [ -n "$HTML5_CONFIG" ]; then echo - echo "/usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml (HTML5 client)" + echo "/var/bigbluebutton/html5-client/private/config/settings.yml (HTML5 client)" echo "/etc/bigbluebutton/bbb-html5.yml (HTML5 client config override)" echo " build: $(echo "$HTML5_CONFIG" | yq e '.public.app.html5ClientBuild' -)" echo " kurentoUrl: $(echo "$HTML5_CONFIG" | yq e '.public.kurento.wsUrl' -)" @@ -1361,7 +1361,6 @@ if [ $ZIP ]; then tar rf $TMP_LOG_FILE /var/log/bbb-apps-akka > /dev/null 2>&1 tar rf $TMP_LOG_FILE /var/log/bbb-fsesl-akka > /dev/null 2>&1 tar rf $TMP_LOG_FILE /var/log/bbb-webrtc-sfu > /dev/null 2>&1 - tar rf $TMP_LOG_FILE /var/log/mongodb > /dev/null 2>&1 tar rf $TMP_LOG_FILE /var/log/redis > /dev/null 2>&1 tar rf $TMP_LOG_FILE /var/log/nginx/error.log* > /dev/null 2>&1 tar rf $TMP_LOG_FILE /var/log/nginx/bigbluebutton.access.log* > /dev/null 2>&1 @@ -1530,7 +1529,6 @@ if [ -n "$HOST" ]; then if [ -f $HTML5_DEFAULT_CONFIG ]; then yq e -i ".public.kurento.wsUrl = \"wss://$HOST/bbb-webrtc-sfu\"" $HTML5_DEFAULT_CONFIG yq e -i ".public.pads.url = \"$PROTOCOL://$HOST/pad\"" $HTML5_DEFAULT_CONFIG - chown meteor:meteor $HTML5_DEFAULT_CONFIG fi # @@ -1545,7 +1543,7 @@ if [ -n "$HOST" ]; then sudo yq e -i ".freeswitch.esl_password = \"$ESL_PASSWORD\"" $WEBRTC_SFU_ETC_CONFIG sudo xmlstarlet edit --inplace --update 'configuration/settings//param[@name="password"]/@value' --value $ESL_PASSWORD /opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml if [ -f /usr/local/bigbluebutton/bbb-transcription-controller/config/default.yml ]; then - sudo yq w -i /usr/local/bigbluebutton/bbb-transcription-controller/config/default.yml freeswitch.password "$ESL_PASSWORD" + sudo yq e -i ".freeswitch.password = \"$ESL_PASSWORD\"" /usr/local/bigbluebutton/bbb-transcription-controller/config/default.yml fi echo "Restarting BigBlueButton $BIGBLUEBUTTON_RELEASE ..." diff --git a/bigbluebutton-html5/.eslintrc.js b/bigbluebutton-html5/.eslintrc.js index e125de9f01..8e956c5c29 100644 --- a/bigbluebutton-html5/.eslintrc.js +++ b/bigbluebutton-html5/.eslintrc.js @@ -21,6 +21,7 @@ module.exports = { 'jsx-a11y/no-access-key': 0, 'react/jsx-props-no-spreading': 'off', 'max-classes-per-file': ['error', 2], + 'react/require-default-props': 0, }, globals: { browser: 'writable', @@ -43,6 +44,7 @@ module.exports = { 'import/extensions': [2, 'never'], 'react/sort-comp': [0], 'react/jsx-filename-extension': ['error', { extensions: ['.tsx', '.jsx'] }], + 'react/require-default-props': 0, 'max-len': [ 'error', { diff --git a/bigbluebutton-html5/.gitignore b/bigbluebutton-html5/.gitignore index 0cbda95da0..dee81bdb2f 100755 --- a/bigbluebutton-html5/.gitignore +++ b/bigbluebutton-html5/.gitignore @@ -5,4 +5,5 @@ node_modules/ public/locales/de_DE.json public/locales/ja_JP.json public/files +dist/ tsconfig.tsbuildinfo diff --git a/bigbluebutton-html5/.meteor/.finished-upgraders b/bigbluebutton-html5/.meteor/.finished-upgraders deleted file mode 100644 index c07b6ff75a..0000000000 --- a/bigbluebutton-html5/.meteor/.finished-upgraders +++ /dev/null @@ -1,19 +0,0 @@ -# This file contains information which helps Meteor properly upgrade your -# app when you run 'meteor update'. You should check it into version control -# with your project. - -notices-for-0.9.0 -notices-for-0.9.1 -0.9.4-platform-file -notices-for-facebook-graph-api-2 -1.2.0-standard-minifiers-package -1.2.0-meteor-platform-split -1.2.0-cordova-changes -1.2.0-breaking-changes -1.3.0-split-minifiers-package -1.4.0-remove-old-dev-bundle-link -1.4.1-add-shell-server-package -1.4.3-split-account-service-packages -1.5-add-dynamic-import-package -1.7-split-underscore-from-meteor-base -1.8.3-split-jquery-from-blaze diff --git a/bigbluebutton-html5/.meteor/.gitignore b/bigbluebutton-html5/.meteor/.gitignore deleted file mode 100644 index 501f92e4b5..0000000000 --- a/bigbluebutton-html5/.meteor/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -dev_bundle -local diff --git a/bigbluebutton-html5/.meteor/.id b/bigbluebutton-html5/.meteor/.id deleted file mode 100644 index 350c3adf10..0000000000 --- a/bigbluebutton-html5/.meteor/.id +++ /dev/null @@ -1,7 +0,0 @@ -# This file contains a token that is unique to your project. -# Check it into your repository along with the rest of this directory. -# It can be used for purposes such as: -# - ensuring you don't accidentally deploy one app on top of another -# - providing package authors with aggregated statistics - -jrnkwdjvicqgy6gtl8 diff --git a/bigbluebutton-html5/.meteor/cordova-plugins b/bigbluebutton-html5/.meteor/cordova-plugins deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/bigbluebutton-html5/.meteor/packages b/bigbluebutton-html5/.meteor/packages deleted file mode 100644 index 1a0016a7ba..0000000000 --- a/bigbluebutton-html5/.meteor/packages +++ /dev/null @@ -1,26 +0,0 @@ -# Meteor packages used by this project, one per line. -# -# 'meteor add' and 'meteor remove' will edit this file for you, -# but you can also edit it by hand. - -meteor-base@1.5.1 -mobile-experience@1.1.0 -mongo@1.16.7 -reactive-var@1.0.12 - -standard-minifier-css@1.9.2 -standard-minifier-js@2.8.1 -es5-shim@4.8.0 -ecmascript@0.16.7 -shell-server@0.5.0 - -static-html@1.3.2 -react-meteor-data -session@1.2.1 -tracker@1.3.2 -check@1.3.2 - -rocketchat:streamer -meteortesting:mocha -lmieulet:meteor-coverage -typescript@4.9.4 diff --git a/bigbluebutton-html5/.meteor/platforms b/bigbluebutton-html5/.meteor/platforms deleted file mode 100644 index efeba1b50c..0000000000 --- a/bigbluebutton-html5/.meteor/platforms +++ /dev/null @@ -1,2 +0,0 @@ -server -browser diff --git a/bigbluebutton-html5/.meteor/release b/bigbluebutton-html5/.meteor/release deleted file mode 100644 index 7c40889daf..0000000000 --- a/bigbluebutton-html5/.meteor/release +++ /dev/null @@ -1 +0,0 @@ -METEOR@2.13 diff --git a/bigbluebutton-html5/.meteor/versions b/bigbluebutton-html5/.meteor/versions deleted file mode 100644 index 4cefbe6d7f..0000000000 --- a/bigbluebutton-html5/.meteor/versions +++ /dev/null @@ -1,78 +0,0 @@ -allow-deny@1.1.1 -autoupdate@1.8.0 -babel-compiler@7.10.4 -babel-runtime@1.5.1 -base64@1.0.12 -binary-heap@1.0.11 -blaze-tools@1.1.3 -boilerplate-generator@1.7.1 -caching-compiler@1.2.2 -caching-html-compiler@1.2.1 -callback-hook@1.5.1 -check@1.3.2 -ddp@1.4.1 -ddp-client@2.6.1 -ddp-common@1.4.0 -ddp-server@2.6.2 -diff-sequence@1.1.2 -dynamic-import@0.7.3 -ecmascript@0.16.7 -ecmascript-runtime@0.8.1 -ecmascript-runtime-client@0.12.1 -ecmascript-runtime-server@0.11.0 -ejson@1.1.3 -es5-shim@4.8.0 -fetch@0.1.3 -geojson-utils@1.0.11 -hot-code-push@1.0.4 -html-tools@1.1.3 -htmljs@1.1.1 -http@2.0.0 -id-map@1.1.1 -inter-process-messaging@0.1.1 -launch-screen@1.3.0 -lmieulet:meteor-coverage@4.1.0 -logging@1.3.2 -meteor@1.11.3 -meteor-base@1.5.1 -meteortesting:browser-tests@1.3.5 -meteortesting:mocha@2.0.3 -meteortesting:mocha-core@8.1.2 -minifier-css@1.6.4 -minifier-js@2.7.5 -minimongo@1.9.3 -mobile-experience@1.1.0 -mobile-status-bar@1.1.0 -modern-browsers@0.1.9 -modules@0.19.0 -modules-runtime@0.13.1 -mongo@1.16.7 -mongo-decimal@0.1.3 -mongo-dev-server@1.1.0 -mongo-id@1.0.8 -npm-mongo@4.16.0 -ordered-dict@1.1.0 -promise@0.12.2 -random@1.2.1 -react-fast-refresh@0.2.7 -react-meteor-data@2.5.1 -reactive-dict@1.3.1 -reactive-var@1.0.12 -reload@1.3.1 -retry@1.1.0 -rocketchat:streamer@1.1.0 -routepolicy@1.1.1 -session@1.2.1 -shell-server@0.5.0 -socket-stream-client@0.5.1 -spacebars-compiler@1.3.1 -standard-minifier-css@1.9.2 -standard-minifier-js@2.8.1 -static-html@1.3.2 -templating-tools@1.2.2 -tracker@1.3.2 -typescript@4.9.4 -underscore@1.0.13 -url@1.3.2 -webapp@1.13.5 -webapp-hashing@1.1.1 diff --git a/bigbluebutton-html5/babel.config.js b/bigbluebutton-html5/babel.config.js new file mode 100644 index 0000000000..6f4718f421 --- /dev/null +++ b/bigbluebutton-html5/babel.config.js @@ -0,0 +1,7 @@ +module.exports = { + presets: [ + '@babel/env', + '@babel/typescript', + '@babel/react', + ], +}; diff --git a/bigbluebutton-html5/client/clientStartup.tsx b/bigbluebutton-html5/client/clientStartup.tsx deleted file mode 100644 index e25ce6ec81..0000000000 --- a/bigbluebutton-html5/client/clientStartup.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React, { - Suspense, - useContext, - useEffect, -} from 'react'; -import { LoadingContext } from '/imports/ui/components/common/loading-screen/loading-screen-HOC/component'; -import logger from '/imports/startup/client/logger'; - -const MeetingClientLazy = React.lazy(() => import('./meetingClient')); - -const ClientStartup: React.FC = () => { - const loadingContextInfo = useContext(LoadingContext); - useEffect(() => { - logger.info('Loading client'); - loadingContextInfo.setLoading(true, '4/4'); - }, []); - - return ( - - { - (() => { - try { - return ; - } catch (error) { - loadingContextInfo.setLoading(false, ''); - throw new Error('Error on rendering MeetingClientLazy: '.concat(JSON.stringify(error) || '')); - } - })() - } - - ); -}; - -export default ClientStartup; diff --git a/bigbluebutton-html5/client/collection-mirror-initializer.js b/bigbluebutton-html5/client/collection-mirror-initializer.js deleted file mode 100644 index 02483381f8..0000000000 --- a/bigbluebutton-html5/client/collection-mirror-initializer.js +++ /dev/null @@ -1,27 +0,0 @@ -import AbstractCollection from '/imports/ui/services/LocalCollectionSynchronizer/LocalCollectionSynchronizer'; - -// Collections -import Screenshare from '/imports/api/screenshare'; -import Breakouts from '/imports/api/breakouts'; -import Meetings, { - MeetingTimeRemaining, Notifications, -} from '/imports/api/meetings'; -import Users from '/imports/api/users'; - -// Custom Publishers -export const localCollectionRegistry = { - localScreenshareSync: new AbstractCollection(Screenshare, Screenshare), - localMeetingTimeRemainingSync: new AbstractCollection(MeetingTimeRemaining, MeetingTimeRemaining), - localBreakoutsSync: new AbstractCollection(Breakouts, Breakouts), - localMeetingsSync: new AbstractCollection(Meetings, Meetings), - localUsersSync: new AbstractCollection(Users, Users), - localNotificationsSync: new AbstractCollection(Notifications, Notifications), -}; - -const collectionMirrorInitializer = () => { - Object.values(localCollectionRegistry).forEach((localCollection) => { - localCollection.setupListeners(); - }); -}; - -export default collectionMirrorInitializer; diff --git a/bigbluebutton-html5/client/legacy.jsx b/bigbluebutton-html5/client/legacy.jsx index a583afff11..d70d6290d4 100755 --- a/bigbluebutton-html5/client/legacy.jsx +++ b/bigbluebutton-html5/client/legacy.jsx @@ -1,5 +1,4 @@ import React from 'react'; -import { Meteor } from 'meteor/meteor'; import { render } from 'react-dom'; import Legacy from '/imports/ui/components/legacy/component'; @@ -7,9 +6,7 @@ import Legacy from '/imports/ui/components/legacy/component'; // What is included here needs to be minimal and carefully considered because some // things can't be polyfilled. -Meteor.startup(() => { - render( - , - document.getElementById('app'), - ); -}); +render( + , + document.getElementById('app'), +); diff --git a/bigbluebutton-html5/client/main.html b/bigbluebutton-html5/client/main.html index 33520fb7ad..125313de36 100755 --- a/bigbluebutton-html5/client/main.html +++ b/bigbluebutton-html5/client/main.html @@ -1,3 +1,4 @@ + @@ -161,7 +171,7 @@ with BigBlueButton; if not, see .
- + +
diff --git a/bigbluebutton-html5/client/main.tsx b/bigbluebutton-html5/client/main.tsx index 80693b7432..16ca5a9958 100644 --- a/bigbluebutton-html5/client/main.tsx +++ b/bigbluebutton-html5/client/main.tsx @@ -9,17 +9,36 @@ import PresenceManager from '/imports/ui/components/join-handler/presenceManager import LoadingScreenHOC from '/imports/ui/components/common/loading-screen/loading-screen-HOC/component'; import IntlLoaderContainer from '/imports/startup/client/intlLoader'; import LocatedErrorBoundary from '/imports/ui/components/common/error-boundary/located-error-boundary/component'; -import StartupDataFetch from '/imports/ui/components/connection-manager/startup-data-fetch/component'; - -import GraphqlToMiniMongoAdapterManager from '/imports/ui/components/components-data/graphqlToMiniMongoAdapterManager/component'; +import CustomUsersSettings from '/imports/ui/components/join-handler/custom-users-settings/component'; +import MeetingClient from '/client/meetingClient'; const STARTUP_CRASH_METADATA = { logCode: 'app_startup_crash', logMessage: 'Possible startup crash' }; const APP_CRASH_METADATA = { logCode: 'app_crash', logMessage: 'Possible app crash' }; +/* eslint-disable */ +if ( + process.env.NODE_ENV === 'production' + // @ts-ignore + && window.__REACT_DEVTOOLS_GLOBAL_HOOK__ +) { + // @ts-ignore + for (const prop in window.__REACT_DEVTOOLS_GLOBAL_HOOK__) { + if (prop === 'renderers') { + // @ts-ignore + // prevents console error when dev tools try to iterate of renderers + window.__REACT_DEVTOOLS_GLOBAL_HOOK__[prop] = new Map(); + continue; + } + // @ts-ignore + window.__REACT_DEVTOOLS_GLOBAL_HOOK__[prop] = typeof window.__REACT_DEVTOOLS_GLOBAL_HOOK__[prop] === 'function' + ? Function.prototype + : null; + } +} +/* eslint-enable */ const Main: React.FC = () => { - // Meteor.disconnect(); return ( - + @@ -27,16 +46,16 @@ const Main: React.FC = () => { - - - + + + - + ); }; diff --git a/bigbluebutton-html5/client/meetingClient.jsx b/bigbluebutton-html5/client/meetingClient.jsx index a2652bbb6e..1718c9e364 100755 --- a/bigbluebutton-html5/client/meetingClient.jsx +++ b/bigbluebutton-html5/client/meetingClient.jsx @@ -18,42 +18,25 @@ /* eslint no-unused-vars: 0 */ import React, { useContext, useEffect } from 'react'; -import { Meteor } from 'meteor/meteor'; import logger from '/imports/startup/client/logger'; import '/imports/ui/services/mobile-app'; import Base from '/imports/startup/client/base'; import ContextProviders from '/imports/ui/components/context-providers/component'; import ConnectionManager from '/imports/ui/components/connection-manager/component'; -import { liveDataEventBrokerInitializer } from '/imports/ui/services/LiveDataEventBroker/LiveDataEventBroker'; // The adapter import is "unused" as far as static code is concerned, but it // needs to here to override global prototypes. So: don't remove it - prlanzarin 25 Apr 2022 import adapter from 'webrtc-adapter'; -import collectionMirrorInitializer from './collection-mirror-initializer'; import { LoadingContext } from '/imports/ui/components/common/loading-screen/loading-screen-HOC/component'; import IntlAdapter from '/imports/startup/client/intlAdapter'; import PresenceAdapter from '../imports/ui/components/presence-adapter/component'; import CustomUsersSettings from '/imports/ui/components/join-handler/custom-users-settings/component'; -import('/imports/api/audio/client/bridge/bridge-whitelist').catch(() => { - // bridge loading -}); - -collectionMirrorInitializer(); -liveDataEventBrokerInitializer(); - // eslint-disable-next-line import/prefer-default-export const Startup = () => { const loadingContextInfo = useContext(LoadingContext); useEffect(() => { - const { disableWebsocketFallback } = window.meetingClientSettings.public.app; loadingContextInfo.setLoading(false, ''); - if (disableWebsocketFallback) { - Meteor.connection._stream._sockjsProtocolsWhitelist = function () { return ['websocket']; }; - - // Meteor.disconnect(); - // Meteor.reconnect(); - } }, []); // Logs all uncaught exceptions to the client logger window.addEventListener('error', (e) => { diff --git a/bigbluebutton-html5/deploy.sh b/bigbluebutton-html5/deploy.sh new file mode 100755 index 0000000000..40f1c94799 --- /dev/null +++ b/bigbluebutton-html5/deploy.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +cd "$(dirname "$0")" + +for var in "$@" +do + if [[ $var == --reset ]] ; then + echo "Performing a full reset..." + rm -rf node_modules + fi +done + +if [ ! -d ./node_modules ] ; then + npm ci --no-progress +fi + +npm run build + +sudo cp -rf dist/* /var/bigbluebutton/html5-client/ + +sudo ln -sf /usr/share/bigbluebutton/nginx/bbb-html5.nginx.static /usr/share/bigbluebutton/nginx/bbb-html5.nginx +sudo systemctl restart nginx + +echo '' +echo '' +echo '----------------' +echo 'bbb-html5 updated' diff --git a/bigbluebutton-html5/deploy_to_usr_share.sh b/bigbluebutton-html5/deploy_to_usr_share.sh deleted file mode 100755 index 4679ae391f..0000000000 --- a/bigbluebutton-html5/deploy_to_usr_share.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/sh -ex -cd "$(dirname "$0")" - -# Please check bigbluebutton/bigbluebutton-html5/dev_local_deployment/README.md - -UPPER_DESTINATION_DIR=/usr/share/meteor -DESTINATION_DIR=$UPPER_DESTINATION_DIR/bundle - -SERVICE_FILES_DIR=/usr/lib/systemd/system -LOCAL_PACKAGING_DIR="$(pwd)/../build/packages-template/bbb-html5" - -if [ ! -d "$LOCAL_PACKAGING_DIR" ]; then - echo "Did not find LOCAL_PACKAGING_DIR=$LOCAL_PACKAGING_DIR" - exit -fi - -sudo rm -rf "$UPPER_DESTINATION_DIR" -sudo mkdir -p "$UPPER_DESTINATION_DIR" -sudo chown -R root:root "$UPPER_DESTINATION_DIR" - -# the next 5 lines may be temporarily commented out if you are sure you are not tweaking the required node_modules after first use of the script. This will save a minute or two during the run of the script -if [ -d "node_modules" ]; then - rm -r node_modules/ -fi -meteor reset -meteor npm ci --production - -sudo chmod 777 /usr/share/meteor -METEOR_DISABLE_OPTIMISTIC_CACHING=1 meteor build $UPPER_DESTINATION_DIR --architecture os.linux.x86_64 --allow-superuser --directory - -sudo chown -R root:root "$UPPER_DESTINATION_DIR"/ -echo 'stage3' - -cd "$DESTINATION_DIR"/programs/server/ || exit -sudo chmod -R 777 . -meteor npm i - -echo "deployed to $DESTINATION_DIR/programs/server\n\n\n" - -echo "writing $DESTINATION_DIR/mongod_start_pre.sh" -sudo cp $LOCAL_PACKAGING_DIR/mongod_start_pre.sh "$DESTINATION_DIR"/mongod_start_pre.sh - -echo "writing $DESTINATION_DIR/mongo-ramdisk.conf" -sudo cp $LOCAL_PACKAGING_DIR/mongo-ramdisk.conf "$DESTINATION_DIR"/mongo-ramdisk.conf - -sudo chown -R root:root "$UPPER_DESTINATION_DIR"/ -sudo chmod +x "$DESTINATION_DIR"/mongod_start_pre.sh - -sudo cp $LOCAL_PACKAGING_DIR/workers-start.sh "$DESTINATION_DIR"/workers-start.sh -sudo chmod +x "$DESTINATION_DIR"/workers-start.sh - -echo "writing $SERVICE_FILES_DIR/bbb-html5.service" -sudo cp $LOCAL_PACKAGING_DIR/bbb-html5.service "$SERVICE_FILES_DIR"/bbb-html5.service - -sudo systemctl daemon-reload - -sudo systemctl restart bbb-html5 diff --git a/bigbluebutton-html5/footer b/bigbluebutton-html5/footer deleted file mode 100644 index 6f8ee55a68..0000000000 --- a/bigbluebutton-html5/footer +++ /dev/null @@ -1,40 +0,0 @@ - - - diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/base.js b/bigbluebutton-html5/imports/api/audio/client/bridge/base.js index 97008cac87..0b40e5d88e 100755 --- a/bigbluebutton-html5/imports/api/audio/client/bridge/base.js +++ b/bigbluebutton-html5/imports/api/audio/client/bridge/base.js @@ -61,7 +61,11 @@ export default class BaseAudioBridge { get inputDeviceId () { return this._inputDeviceId; + } + /* eslint-disable class-methods-use-this */ + supportsTransparentListenOnly() { + return false; } /** @@ -78,6 +82,20 @@ export default class BaseAudioBridge { let backupStream; try { + // Remove all input audio tracks from the stream + // This will effectively mute the microphone + // and keep the audio output working + if (deviceId === 'listen-only') { + const stream = this.inputStream; + if (stream) { + stream.getAudioTracks().forEach((track) => { + track.stop(); + stream.removeTrack(track); + }); + } + return stream; + } + const constraints = { audio: getAudioConstraints({ deviceId }), }; diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/bridge-whitelist.js b/bigbluebutton-html5/imports/api/audio/client/bridge/bridge-whitelist.js deleted file mode 100644 index 1f2cd0a9ce..0000000000 --- a/bigbluebutton-html5/imports/api/audio/client/bridge/bridge-whitelist.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Bridge whitelist, needed for dynamically importing bridges (as modules). - * - * The code is intentionally unreachable, but its trigger Meteor's static - * analysis, which makes bridge module available to build process. - * - * For new bridges, we must append an import statement here. - * - * More information here: - *https://docs.meteor.com/packages/dynamic-import.html - */ - -throw new Error(); - -/* eslint-disable no-unreachable */ -// BRIDGES LIST -import('/imports/api/audio/client/bridge/FullAudioBridge'); // NOSONAR diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/service.js b/bigbluebutton-html5/imports/api/audio/client/bridge/service.js index e701ae57e0..980005722d 100644 --- a/bigbluebutton-html5/imports/api/audio/client/bridge/service.js +++ b/bigbluebutton-html5/imports/api/audio/client/bridge/service.js @@ -1,19 +1,12 @@ -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import logger from '/imports/startup/client/logger'; -import BBBStorage from '/imports/ui/services/storage'; +import { getStorageSingletonInstance } from '/imports/ui/services/storage'; const AUDIO_SESSION_NUM_KEY = 'AudioSessionNumber'; const DEFAULT_INPUT_DEVICE_ID = ''; const DEFAULT_OUTPUT_DEVICE_ID = ''; const INPUT_DEVICE_ID_KEY = 'audioInputDeviceId'; const OUTPUT_DEVICE_ID_KEY = 'audioOutputDeviceId'; -const AUDIO_MICROPHONE_CONSTRAINTS = Meteor.settings.public.app.defaultSettings - .application.microphoneConstraints; -const MEDIA_TAG = Meteor.settings.public.media.mediaTag; - -const CONFIG = window.meetingClientSettings.public.app.audioCaptions; -const PROVIDER = CONFIG.provider; -const audioCaptionsEnabled = window.meetingClientSettings.public.app.audioCaptions.enabled; const getAudioSessionNumber = () => { let currItem = parseInt(sessionStorage.getItem(AUDIO_SESSION_NUM_KEY), 10); @@ -38,14 +31,30 @@ const reloadAudioElement = (audioElement) => { }; const getCurrentAudioSinkId = () => { + const MEDIA_TAG = window.meetingClientSettings.public.media.mediaTag; const audioElement = document.querySelector(MEDIA_TAG); return audioElement?.sinkId || DEFAULT_OUTPUT_DEVICE_ID; }; -const getStoredAudioInputDeviceId = () => BBBStorage.getItem(INPUT_DEVICE_ID_KEY); -const getStoredAudioOutputDeviceId = () => BBBStorage.getItem(OUTPUT_DEVICE_ID_KEY); -const storeAudioInputDeviceId = (deviceId) => BBBStorage.setItem(INPUT_DEVICE_ID_KEY, deviceId); -const storeAudioOutputDeviceId = (deviceId) => BBBStorage.setItem(OUTPUT_DEVICE_ID_KEY, deviceId); +const getStoredAudioOutputDeviceId = () => getStorageSingletonInstance() + .getItem(OUTPUT_DEVICE_ID_KEY); +const storeAudioOutputDeviceId = (deviceId) => getStorageSingletonInstance() + .setItem(OUTPUT_DEVICE_ID_KEY, deviceId); +const getStoredAudioInputDeviceId = () => getStorageSingletonInstance() + .getItem(INPUT_DEVICE_ID_KEY); +const storeAudioInputDeviceId = (deviceId) => { + if (deviceId === 'listen-only') { + // Do not store listen-only "devices" and remove any stored device + // So it starts from scratch next time. + getStorageSingletonInstance().removeItem(INPUT_DEVICE_ID_KEY); + + return false; + } + + getStorageSingletonInstance().setItem(INPUT_DEVICE_ID_KEY, deviceId); + + return true; +}; /** * Filter constraints set in audioDeviceConstraints, based on @@ -81,9 +90,11 @@ const filterSupportedConstraints = (audioDeviceConstraints) => { const getAudioConstraints = (constraintFields = {}) => { const { deviceId = '' } = constraintFields; + const Settings = getSettingsSingletonInstance(); const userSettingsConstraints = Settings.application.microphoneConstraints; const audioDeviceConstraints = userSettingsConstraints - || AUDIO_MICROPHONE_CONSTRAINTS || {}; + || window.meetingClientSettings.public.app.defaultSettings.application.microphoneConstraints + || {}; const matchConstraints = filterSupportedConstraints( audioDeviceConstraints, @@ -119,15 +130,17 @@ const doGUM = async (constraints, retryOnFailure = false) => { } }; -const isEnabled = () => audioCaptionsEnabled; +const isEnabled = () => window.meetingClientSettings.public.app.audioCaptions.enabled; -const isWebSpeechApi = () => PROVIDER === 'webspeech'; +const getProvider = () => window.meetingClientSettings.public.app.audioCaptions.provider; -const isVosk = () => PROVIDER === 'vosk'; +const isWebSpeechApi = () => getProvider() === 'webspeech'; -const isWhispering = () => PROVIDER === 'whisper'; +const isVosk = () => getProvider() === 'vosk'; -const isDeepSpeech = () => PROVIDER === 'deepSpeech'; +const isWhispering = () => getProvider() === 'whisper'; + +const isDeepSpeech = () => getProvider() === 'deepSpeech'; const isActive = () => isEnabled() && ((isWebSpeechApi()) || isVosk() || isWhispering() || isDeepSpeech()); diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/sfu-audio-bridge.js b/bigbluebutton-html5/imports/api/audio/client/bridge/sfu-audio-bridge.js index dacdbc1a50..82ac15ce58 100755 --- a/bigbluebutton-html5/imports/api/audio/client/bridge/sfu-audio-bridge.js +++ b/bigbluebutton-html5/imports/api/audio/client/bridge/sfu-audio-bridge.js @@ -18,22 +18,9 @@ import { } from '/imports/api/audio/client/bridge/service'; import { shouldForceRelay } from '/imports/ui/services/bbb-webrtc-sfu/utils'; -const SFU_URL = Meteor.settings.public.kurento.wsUrl; -const DEFAULT_LISTENONLY_MEDIA_SERVER = Meteor.settings.public.kurento.listenOnlyMediaServer; -const SIGNAL_CANDIDATES = Meteor.settings.public.kurento.signalCandidates; -const TRACE_LOGS = Meteor.settings.public.kurento.traceLogs; -const GATHERING_TIMEOUT = Meteor.settings.public.kurento.gatheringTimeout; -const MEDIA = Meteor.settings.public.media; -const DEFAULT_FULLAUDIO_MEDIA_SERVER = MEDIA.audio.fullAudioMediaServer; -const RETRY_THROUGH_RELAY = MEDIA.audio.retryThroughRelay || false; -const LISTEN_ONLY_OFFERING = MEDIA.listenOnlyOffering; -const FULLAUDIO_OFFERING = MEDIA.fullAudioOffering; -const TRANSPARENT_LISTEN_ONLY = MEDIA.transparentListenOnly; -const MEDIA_TAG = MEDIA.mediaTag.replace(/#/g, ''); -const CONNECTION_TIMEOUT_MS = MEDIA.listenOnlyCallTimeout || 15000; -const { audio: NETWORK_PRIORITY } = MEDIA.networkPriorities || {}; const SENDRECV_ROLE = 'sendrecv'; const RECV_ROLE = 'recv'; +const PASSIVE_SENDRECV_ROLE = 'passive-sendrecv'; const BRIDGE_NAME = 'fullaudio'; const IS_CHROME = browserInfo.isChrome; @@ -61,6 +48,11 @@ const mapErrorCode = (error) => { }; const getMediaServerAdapter = (listenOnly = false) => { + const SETTINGS = window.meetingClientSettings; + const MEDIA = SETTINGS.public.media; + const DEFAULT_LISTENONLY_MEDIA_SERVER = SETTINGS.public.kurento.listenOnlyMediaServer; + const DEFAULT_FULLAUDIO_MEDIA_SERVER = MEDIA.audio.fullAudioMediaServer; + if (listenOnly) { return getFromMeetingSettings( 'media-server-listenonly', @@ -74,14 +66,23 @@ const getMediaServerAdapter = (listenOnly = false) => { ); }; -const isTransparentListenOnlyEnabled = () => getFromUserSettings( - 'bbb_transparent_listen_only', - TRANSPARENT_LISTEN_ONLY, -); +const isTransparentListenOnlyEnabled = () => { + const SETTINGS = window.meetingClientSettings; + const MEDIA = SETTINGS.public.media; + const TRANSPARENT_LISTEN_ONLY = MEDIA.transparentListenOnly; + return getFromUserSettings( + 'bbb_transparent_listen_only', + TRANSPARENT_LISTEN_ONLY, + ); +}; export default class SFUAudioBridge extends BaseAudioBridge { static getOfferingRole(isListenOnly) { - return isListenOnly + const SETTINGS = window.meetingClientSettings; + const MEDIA = SETTINGS.public.media; + const LISTEN_ONLY_OFFERING = MEDIA.listenOnlyOffering; + const FULLAUDIO_OFFERING = MEDIA.fullAudioOffering; + return isListenOnly && !isTransparentListenOnlyEnabled() ? LISTEN_ONLY_OFFERING : (!isTransparentListenOnlyEnabled() && FULLAUDIO_OFFERING); } @@ -95,12 +96,17 @@ export default class SFUAudioBridge extends BaseAudioBridge { this.reconnecting = false; this.iceServers = []; this.bridgeName = BRIDGE_NAME; + this.isListenOnly = false; + this.bypassGUM = false; + this.supportsTransparentListenOnly = isTransparentListenOnlyEnabled; this.handleTermination = this.handleTermination.bind(this); } get inputStream() { - if (this.broker) { + // Only return the stream if the broker is active and the role isn't recvonly + // Input stream == actual input-capturing stream, not the one that's being played + if (this.broker && this.role !== RECV_ROLE) { return this.broker.getLocalStream(); } @@ -111,6 +117,18 @@ export default class SFUAudioBridge extends BaseAudioBridge { return this.broker?.role; } + getBrokerRole({ hasInputStream }) { + if (this.isListenOnly) { + return isTransparentListenOnlyEnabled() + ? PASSIVE_SENDRECV_ROLE + : RECV_ROLE; + } + + if (this.bypassGUM && !hasInputStream) return PASSIVE_SENDRECV_ROLE; + + return SENDRECV_ROLE; + } + setInputStream(stream) { if (this.broker == null) return null; @@ -133,6 +151,10 @@ export default class SFUAudioBridge extends BaseAudioBridge { setConnectionTimeout() { if (this.connectionTimeout) this.clearConnectionTimeout(); + const SETTINGS = window.meetingClientSettings; + const MEDIA = SETTINGS.public.media; + const CONNECTION_TIMEOUT_MS = MEDIA.listenOnlyCallTimeout || 15000; + this.connectionTimeout = setTimeout(() => { const error = new Error(`ICE negotiation timeout after ${CONNECTION_TIMEOUT_MS / 1000}s`); error.errorCode = 1010; @@ -192,6 +214,9 @@ export default class SFUAudioBridge extends BaseAudioBridge { this.clearConnectionTimeout(); mapErrorCode(error); const { errorMessage, errorCause, errorCode } = error; + const SETTINGS = window.meetingClientSettings; + const MEDIA = SETTINGS.public.media; + const RETRY_THROUGH_RELAY = MEDIA.audio.retryThroughRelay || false; if (!this.reconnecting) { if (this.broker.started) { @@ -257,6 +282,9 @@ export default class SFUAudioBridge extends BaseAudioBridge { } handleStart() { + const SETTINGS = window.meetingClientSettings; + const MEDIA = SETTINGS.public.media; + const MEDIA_TAG = MEDIA.mediaTag.replace(/#/g, ''); const stream = this.broker.webRtcPeer.getRemoteStream(); const mediaElement = document.getElementById(MEDIA_TAG); @@ -316,8 +344,18 @@ export default class SFUAudioBridge extends BaseAudioBridge { extension, inputStream, forceRelay: _forceRelay = false, + bypassGUM = false, } = options; + const SETTINGS = window.meetingClientSettings; + const MEDIA = SETTINGS.public.media; + const SIGNAL_CANDIDATES = SETTINGS.public.kurento.signalCandidates; + const SFU_URL = SETTINGS.public.kurento.wsUrl; + const TRACE_LOGS = SETTINGS.public.kurento.traceLogs; + const GATHERING_TIMEOUT = SETTINGS.public.kurento.gatheringTimeout; + const RETRY_THROUGH_RELAY = MEDIA.audio.retryThroughRelay || false; + const { audio: NETWORK_PRIORITY } = MEDIA.networkPriorities || {}; + const handleInitError = (_error) => { mapErrorCode(_error); if (RETRYABLE_ERRORS.includes(_error?.errorCode) @@ -330,6 +368,10 @@ export default class SFUAudioBridge extends BaseAudioBridge { try { this.inEchoTest = !!extension; this.isListenOnly = isListenOnly; + this.bypassGUM = bypassGUM; + const role = this.getBrokerRole({ + hasInputStream: !!inputStream, + }); const brokerOptions = { clientSessionNumber: getAudioSessionNumber(), @@ -346,11 +388,12 @@ export default class SFUAudioBridge extends BaseAudioBridge { mediaStreamFactory: this.mediaStreamFactory, gatheringTimeout: GATHERING_TIMEOUT, transparentListenOnly: isTransparentListenOnlyEnabled(), + bypassGUM, }; this.broker = new AudioBroker( Auth.authenticateURL(SFU_URL), - isListenOnly ? RECV_ROLE : SENDRECV_ROLE, + role, brokerOptions, ); @@ -422,6 +465,13 @@ export default class SFUAudioBridge extends BaseAudioBridge { try { fetchWebRTCMappedStunTurnServers(this.sessionToken) .then((iceServers) => { + const SETTINGS = window.meetingClientSettings; + const MEDIA = SETTINGS.public.media; + const SFU_URL = SETTINGS.public.kurento.wsUrl; + const TRACE_LOGS = SETTINGS.public.kurento.traceLogs; + const GATHERING_TIMEOUT = SETTINGS.public.kurento.gatheringTimeout; + const LISTEN_ONLY_OFFERING = MEDIA.listenOnlyOffering; + const options = { clientSessionNumber: getAudioSessionNumber(), iceServers, @@ -461,6 +511,9 @@ export default class SFUAudioBridge extends BaseAudioBridge { } exitAudio() { + const SETTINGS = window.meetingClientSettings; + const MEDIA = SETTINGS.public.media; + const MEDIA_TAG = MEDIA.mediaTag.replace(/#/g, ''); const mediaElement = document.getElementById(MEDIA_TAG); this.clearConnectionTimeout(); @@ -479,5 +532,3 @@ export default class SFUAudioBridge extends BaseAudioBridge { return Promise.resolve(); } } - -module.exports = SFUAudioBridge; diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js index ed1ed9a3f0..a7a9516e9d 100755 --- a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js +++ b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js @@ -23,28 +23,9 @@ import { stereoUnsupported, } from '/imports/api/audio/client/bridge/service'; -const MEDIA = Meteor.settings.public.media; -const MEDIA_TAG = MEDIA.mediaTag; -const CALL_HANGUP_TIMEOUT = MEDIA.callHangupTimeout; -const CALL_HANGUP_MAX_RETRIES = MEDIA.callHangupMaximumRetries; -const SIPJS_HACK_VIA_WS = MEDIA.sipjsHackViaWs; -const SIPJS_ALLOW_MDNS = MEDIA.sipjsAllowMdns || false; -const IPV4_FALLBACK_DOMAIN = Meteor.settings.public.app.ipv4FallbackDomain; const CALL_CONNECT_TIMEOUT = 20000; const ICE_NEGOTIATION_TIMEOUT = 20000; -const USER_AGENT_RECONNECTION_ATTEMPTS = MEDIA.audioReconnectionAttempts || 3; -const USER_AGENT_RECONNECTION_DELAY_MS = MEDIA.audioReconnectionDelay || 5000; -const USER_AGENT_CONNECTION_TIMEOUT_MS = MEDIA.audioConnectionTimeout || 5000; -const ICE_GATHERING_TIMEOUT = MEDIA.iceGatheringTimeout || 5000; const BRIDGE_NAME = 'sip'; -const WEBSOCKET_KEEP_ALIVE_INTERVAL = MEDIA.websocketKeepAliveInterval || 0; -const WEBSOCKET_KEEP_ALIVE_DEBOUNCE = MEDIA.websocketKeepAliveDebounce || 10; -const TRACE_SIP = MEDIA.traceSip || false; -const SDP_SEMANTICS = MEDIA.sdpSemantics; -const FORCE_RELAY = MEDIA.forceRelay; - -const UA_SERVER_VERSION = Meteor.settings.public.app.bbbServerVersion; -const UA_CLIENT_VERSION = Meteor.settings.public.app.html5ClientBuild; /** * Get error code from SIP.js websocket messages. @@ -132,6 +113,8 @@ class SIPSession { get outputDeviceId() { if (!this._outputDeviceId) { + const MEDIA = window.meetingClientSettings.public.media; + const MEDIA_TAG = MEDIA.mediaTag; const audioElement = document.querySelector(MEDIA_TAG); if (audioElement) { this._outputDeviceId = audioElement.sinkId; @@ -306,6 +289,10 @@ class SIPSession { this.userRequestedHangup = true; + const MEDIA = window.meetingClientSettings.public.media; + const CALL_HANGUP_TIMEOUT = MEDIA.callHangupTimeout; + const CALL_HANGUP_MAX_RETRIES = MEDIA.callHangupMaximumRetries; + const tryHangup = () => { if (this._hangupFlag) { resolve(); @@ -388,6 +375,18 @@ class SIPSession { createUserAgent(iceServers) { return new Promise((resolve, reject) => { + const MEDIA = window.meetingClientSettings.public.media; + const SIPJS_HACK_VIA_WS = MEDIA.sipjsHackViaWs; + const USER_AGENT_RECONNECTION_ATTEMPTS = MEDIA.audioReconnectionAttempts || 3; + const USER_AGENT_CONNECTION_TIMEOUT_MS = MEDIA.audioConnectionTimeout || 5000; + const WEBSOCKET_KEEP_ALIVE_INTERVAL = MEDIA.websocketKeepAliveInterval || 0; + const WEBSOCKET_KEEP_ALIVE_DEBOUNCE = MEDIA.websocketKeepAliveDebounce || 10; + const TRACE_SIP = MEDIA.traceSip || false; + const SDP_SEMANTICS = MEDIA.sdpSemantics; + const FORCE_RELAY = MEDIA.forceRelay; + const UA_SERVER_VERSION = window.meetingClientSettings.public.app.bbbServerVersion; + const UA_CLIENT_VERSION = window.meetingClientSettings.public.app.html5ClientBuild; + if (this.userRequestedHangup === true) reject(); const { @@ -599,6 +598,10 @@ class SIPSession { return resolve(); } + const MEDIA = window.meetingClientSettings.public.media; + const USER_AGENT_RECONNECTION_ATTEMPTS = MEDIA.audioReconnectionAttempts || 3; + const USER_AGENT_RECONNECTION_DELAY_MS = MEDIA.audioReconnectionDelay || 5000; + if (attempts > USER_AGENT_RECONNECTION_ATTEMPTS) { return reject({ type: this.baseErrorCodes.CONNECTION_ERROR, @@ -710,6 +713,10 @@ class SIPSession { filterValidIceCandidates.bind(this, this.validIceCandidates), ]; + const MEDIA = window.meetingClientSettings.public.media; + const SIPJS_ALLOW_MDNS = MEDIA.sipjsAllowMdns || false; + const ICE_GATHERING_TIMEOUT = MEDIA.iceGatheringTimeout || 5000; + if (!SIPJS_ALLOW_MDNS) iceModifiers.push(stripMDnsCandidates); // The current Vosk provider does not support stereo when transcribing @@ -768,6 +775,8 @@ class SIPSession { let sessionTerminated = false; const setupRemoteMedia = () => { + const MEDIA = window.meetingClientSettings.public.media; + const MEDIA_TAG = MEDIA.mediaTag; const mediaElement = document.querySelector(MEDIA_TAG); const { sdp } = this.currentSession.sessionDescriptionHandler .peerConnection.remoteDescription; @@ -1131,6 +1140,8 @@ export default class SIPBridge extends BaseAudioBridge { constructor(userData) { super(userData); + const MEDIA = window.meetingClientSettings.public.media; + const { userId, username, @@ -1186,6 +1197,7 @@ export default class SIPBridge extends BaseAudioBridge { validIceCandidates, inputStream, }, managerCallback) { + const IPV4_FALLBACK_DOMAIN = window.meetingClientSettings.public.app.ipv4FallbackDomain; const hasFallbackDomain = typeof IPV4_FALLBACK_DOMAIN === 'string' && IPV4_FALLBACK_DOMAIN !== ''; return new Promise((resolve, reject) => { @@ -1294,5 +1306,3 @@ export default class SIPBridge extends BaseAudioBridge { return this.activeSession.updateAudioConstraints(constraints); } } - -module.exports = SIPBridge; diff --git a/bigbluebutton-html5/imports/api/bbb-web-api/index.ts b/bigbluebutton-html5/imports/api/bbb-web-api/index.ts new file mode 100644 index 0000000000..837fd710bd --- /dev/null +++ b/bigbluebutton-html5/imports/api/bbb-web-api/index.ts @@ -0,0 +1,50 @@ +import Session from '/imports/ui/services/storage/session'; +import { IndexResponse } from './types'; + +class BBBWebApi { + private cachePrefix = 'bbbWebApi'; + + private routes = { + index: { + path: '/bigbluebutton/api', + cacheKey: `${this.cachePrefix}_index`, + }, + }; + + private static buildURL(route: string) { + const pathMatch = window.location.pathname.match('^(.*)/html5client/join$'); + const serverPathPrefix = pathMatch ? pathMatch[1] : ''; + const { hostname, protocol } = window.location; + return new URL(route, `${protocol}//${hostname}${serverPathPrefix}`); + } + + public async index(signal?: AbortSignal): Promise<{ + data: IndexResponse['response'], + response?: Response, + }> { + const cache = Session.getItem(this.routes.index.cacheKey); + if (cache) { + return { + data: cache as IndexResponse['response'], + }; + } + + const response = await fetch(BBBWebApi.buildURL(this.routes.index.path), { + headers: { + 'Content-Type': 'application/json', + }, + signal, + }); + + const body: IndexResponse = await response.json(); + Session.setItem(this.routes.index.cacheKey, body.response); + + return { + response, + data: body.response, + }; + } +} + +const BBBWeb = new BBBWebApi(); +export default BBBWeb; diff --git a/bigbluebutton-html5/imports/api/bbb-web-api/types.ts b/bigbluebutton-html5/imports/api/bbb-web-api/types.ts new file mode 100644 index 0000000000..c239307c17 --- /dev/null +++ b/bigbluebutton-html5/imports/api/bbb-web-api/types.ts @@ -0,0 +1,10 @@ +export interface IndexResponse { + response: { + returncode: string; + version: string; + apiVersion: string; + bbbVersion: string; + graphqlApiUrl: string; + graphqlWebsocketUrl: string; + } +} diff --git a/bigbluebutton-html5/imports/api/breakouts/index.js b/bigbluebutton-html5/imports/api/breakouts/index.js deleted file mode 100644 index ce89c17bdf..0000000000 --- a/bigbluebutton-html5/imports/api/breakouts/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -const collectionOptions = Meteor.isClient ? { - connection: null, -} : {}; - -const Breakouts = new Mongo.Collection('breakouts', collectionOptions); - -if (Meteor.isServer) { - // types of queries for the breakouts: - // 1. breakoutId ( handleJoinUrl, roomStarted, clearBreakouts ) - // 2. parentMeetingId ( updateTimeRemaining ) - - Breakouts.createIndexAsync({ breakoutId: 1 }); - Breakouts.createIndexAsync({ parentMeetingId: 1 }); -} - -export default Breakouts; diff --git a/bigbluebutton-html5/imports/api/common/server/helpers.js b/bigbluebutton-html5/imports/api/common/server/helpers.js deleted file mode 100755 index 35ac42a70a..0000000000 --- a/bigbluebutton-html5/imports/api/common/server/helpers.js +++ /dev/null @@ -1,101 +0,0 @@ -import Users from '/imports/api/users'; -import Logger from '/imports/startup/server/logger'; -import RegexWebUrl from '/imports/utils/regex-weburl'; -import { BREAK_LINE } from '/imports/utils/lineEndings'; - -const MSG_DIRECT_TYPE = 'DIRECT'; -const NODE_USER = 'nodeJSapp'; - -const HTML_SAFE_MAP = { - '<': '<', - '>': '>', - '"': '"', - "'": ''', -}; - -export const parseMessage = (message) => { - let parsedMessage = message || ''; - parsedMessage = parsedMessage.trim(); - - // Replace
with \n\r - parsedMessage = parsedMessage.replace(//gi, '\n\r'); - - // Sanitize. See: http://shebang.brandonmintern.com/foolproof-html-escaping-in-javascript/ - parsedMessage = parsedMessage.replace(/[<>'"]/g, (c) => HTML_SAFE_MAP[c]); - - // Replace flash links to flash valid ones - parsedMessage = parsedMessage.replace(RegexWebUrl, "
$&"); - - // Replace flash links to html valid ones - parsedMessage = parsedMessage.split(' { - stopped = true; - Logger.info(`Publication ${self._name} has stopped in server side`); - }); - - periodicCheck(); -}; diff --git a/bigbluebutton-html5/imports/api/log-client/server/index.js b/bigbluebutton-html5/imports/api/log-client/server/index.js deleted file mode 100644 index ba55c4a16e..0000000000 --- a/bigbluebutton-html5/imports/api/log-client/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import './methods'; diff --git a/bigbluebutton-html5/imports/api/log-client/server/methods.js b/bigbluebutton-html5/imports/api/log-client/server/methods.js deleted file mode 100644 index 66db1a2d72..0000000000 --- a/bigbluebutton-html5/imports/api/log-client/server/methods.js +++ /dev/null @@ -1,4 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import logClient from './methods/logClient'; - -Meteor.methods({ logClient }); diff --git a/bigbluebutton-html5/imports/api/log-client/server/methods/logClient.js b/bigbluebutton-html5/imports/api/log-client/server/methods/logClient.js deleted file mode 100755 index 44d1559799..0000000000 --- a/bigbluebutton-html5/imports/api/log-client/server/methods/logClient.js +++ /dev/null @@ -1,15 +0,0 @@ -import Logger from '/imports/startup/server/logger'; - -export default function (type, logDescription, logCode = 'was_not_provided', extraInfo = {}, userInfo = {}) { - const connectionId = this.connection.id; - const logContents = { - logCode, - logDescription, - connectionId, - extraInfo, - userInfo, - }; - - // If I don't pass message, logs will start with `undefined` - Logger.log({ message: JSON.stringify(logContents), level: type }); -} diff --git a/bigbluebutton-html5/imports/api/meetings/index.js b/bigbluebutton-html5/imports/api/meetings/index.js deleted file mode 100644 index a732eb71fb..0000000000 --- a/bigbluebutton-html5/imports/api/meetings/index.js +++ /dev/null @@ -1,26 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -const collectionOptions = Meteor.isClient ? { - connection: null, -} : {}; - -const Meetings = new Mongo.Collection('meetings', collectionOptions); -const MeetingTimeRemaining = new Mongo.Collection('meeting-time-remaining', collectionOptions); -const Notifications = new Mongo.Collection('notifications', collectionOptions); -const LayoutMeetings = new Mongo.Collection('layout-meetings'); - -if (Meteor.isServer) { - // types of queries for the meetings: - // 1. meetingId - - Meetings.createIndexAsync({ meetingId: 1 }); - MeetingTimeRemaining.createIndexAsync({ meetingId: 1 }); - LayoutMeetings.createIndexAsync({ meetingId: 1 }); -} - -export { - MeetingTimeRemaining, - Notifications, - LayoutMeetings, -}; -export default Meetings; diff --git a/bigbluebutton-html5/imports/api/presentations/index.js b/bigbluebutton-html5/imports/api/presentations/index.js deleted file mode 100644 index f95c193c99..0000000000 --- a/bigbluebutton-html5/imports/api/presentations/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -const collectionOptions = Meteor.isClient ? { - connection: null, -} : {}; - -export const UploadingPresentations = Meteor.isClient ? new Mongo.Collection('uploadingPresentations', collectionOptions) : null; - -export default UploadingPresentations; diff --git a/bigbluebutton-html5/imports/api/screenshare/client/bridge/kurento.js b/bigbluebutton-html5/imports/api/screenshare/client/bridge/kurento.js index 71d1aaa32d..96077f3148 100755 --- a/bigbluebutton-html5/imports/api/screenshare/client/bridge/kurento.js +++ b/bigbluebutton-html5/imports/api/screenshare/client/bridge/kurento.js @@ -8,14 +8,6 @@ import { shouldForceRelay } from '/imports/ui/services/bbb-webrtc-sfu/utils'; import MediaStreamUtils from '/imports/utils/media-stream-utils'; import { notifyStreamStateChange } from '/imports/ui/services/bbb-webrtc-sfu/stream-state-service'; -const SFU_CONFIG = Meteor.settings.public.kurento; -const SFU_URL = SFU_CONFIG.wsUrl; -const OFFERING = SFU_CONFIG.screenshare.subscriberOffering; -const SIGNAL_CANDIDATES = Meteor.settings.public.kurento.signalCandidates; -const TRACE_LOGS = Meteor.settings.public.kurento.traceLogs; -const { screenshare: NETWORK_PRIORITY } = Meteor.settings.public.media.networkPriorities || {}; -const GATHERING_TIMEOUT = Meteor.settings.public.kurento.gatheringTimeout; - const BRIDGE_NAME = 'kurento' const SCREENSHARE_VIDEO_TAG = 'screenshareVideo'; const SEND_ROLE = 'send'; @@ -52,11 +44,19 @@ export default class KurentoScreenshareBridge { this.connectionAttempts = 0; this.reconnecting = false; this.reconnectionTimeout; - this.restartIntervalMs = BridgeService.BASE_MEDIA_TIMEOUT; + this._restartIntervalMs = null; this.startedOnce = false; this.outputDeviceId = null; } + get restartIntervalMs() { + return this._restartIntervalMs || BridgeService.BASE_MEDIA_TIMEOUT(); + } + + set restartIntervalMs(value) { + this._restartIntervalMs = value; + } + get gdmStream() { return this._gdmStream; } @@ -147,7 +147,7 @@ export default class KurentoScreenshareBridge { } maxConnectionAttemptsReached () { - return this.connectionAttempts > BridgeService.MAX_CONN_ATTEMPTS; + return this.connectionAttempts > BridgeService.MAX_CONN_ATTEMPTS(); } scheduleReconnect({ @@ -166,7 +166,7 @@ export default class KurentoScreenshareBridge { clearReconnectionTimeout () { this.reconnecting = false; - this.restartIntervalMs = BridgeService.BASE_MEDIA_TIMEOUT; + this.restartIntervalMs = BridgeService.BASE_MEDIA_TIMEOUT(); if (this.reconnectionTimeout) { clearTimeout(this.reconnectionTimeout); @@ -242,7 +242,7 @@ export default class KurentoScreenshareBridge { if (this.broker?.started) { overrideTimeout = 0; } else if (this.startedOnce) { - overrideTimeout = BridgeService.BASE_RECONNECTION_TIMEOUT; + overrideTimeout = BridgeService.BASE_RECONNECTION_TIMEOUT(); } this.scheduleReconnect({ overrideTimeout }); @@ -255,6 +255,13 @@ export default class KurentoScreenshareBridge { hasAudio: false, outputDeviceId: null, }) { + const SETTINGS = window.meetingClientSettings; + const SFU_CONFIG = SETTINGS.public.kurento; + const SFU_URL = SFU_CONFIG.wsUrl; + const OFFERING = SFU_CONFIG.screenshare.subscriberOffering; + const SIGNAL_CANDIDATES = SFU_CONFIG.signalCandidates; + const TRACE_LOGS = SFU_CONFIG.traceLogs; + const GATHERING_TIMEOUT = SFU_CONFIG.gatheringTimeout; this.hasAudio = options.hasAudio; this.outputDeviceId = options.outputDeviceId; this.role = RECV_ROLE; @@ -304,6 +311,13 @@ export default class KurentoScreenshareBridge { share(stream, onFailure, contentType) { return new Promise(async (resolve, reject) => { + const SETTINGS = window.meetingClientSettings; + const SFU_CONFIG = SETTINGS.public.kurento; + const SFU_URL = SFU_CONFIG.wsUrl; + const SIGNAL_CANDIDATES = SFU_CONFIG.signalCandidates; + const TRACE_LOGS = SFU_CONFIG.traceLogs; + const { screenshare: NETWORK_PRIORITY } = SETTINGS.public.media.networkPriorities || {}; + const GATHERING_TIMEOUT = SFU_CONFIG.gatheringTimeout; this.onerror = onFailure; this.connectionAttempts += 1; this.role = SEND_ROLE; @@ -333,7 +347,7 @@ export default class KurentoScreenshareBridge { stream, hasAudio: this.hasAudio, contentType: contentType, - bitrate: BridgeService.BASE_BITRATE, + bitrate: BridgeService.BASE_BITRATE(), offering: true, mediaServer: BridgeService.getMediaServerAdapter(), signalCandidates: SIGNAL_CANDIDATES, diff --git a/bigbluebutton-html5/imports/api/screenshare/client/bridge/service.js b/bigbluebutton-html5/imports/api/screenshare/client/bridge/service.js index e6e8075e5f..e2886f10aa 100644 --- a/bigbluebutton-html5/imports/api/screenshare/client/bridge/service.js +++ b/bigbluebutton-html5/imports/api/screenshare/client/bridge/service.js @@ -1,28 +1,13 @@ -import Meetings from '/imports/api/meetings'; import logger from '/imports/startup/client/logger'; import { fetchWebRTCMappedStunTurnServers, getMappedFallbackStun } from '/imports/utils/fetchStunTurnServers'; import loadAndPlayMediaStream from '/imports/ui/services/bbb-webrtc-sfu/load-play'; import { SCREENSHARING_ERRORS } from './errors'; -import getFromMeetingSettings from '/imports/ui/services/meeting-settings'; - -const { - constraints: GDM_CONSTRAINTS, - mediaTimeouts: MEDIA_TIMEOUTS, - bitrate: BASE_BITRATE, - mediaServer: DEFAULT_SCREENSHARE_MEDIA_SERVER, -} = Meteor.settings.public.kurento.screenshare; -const { - baseTimeout: BASE_MEDIA_TIMEOUT, - maxTimeout: MAX_MEDIA_TIMEOUT, - maxConnectionAttempts: MAX_CONN_ATTEMPTS, - timeoutIncreaseFactor: TIMEOUT_INCREASE_FACTOR, - baseReconnectionTimeout: BASE_RECONNECTION_TIMEOUT, -} = MEDIA_TIMEOUTS; +import getFromMeetingSettings, { getVoiceConf } from '/imports/ui/services/meeting-settings'; const HAS_DISPLAY_MEDIA = (typeof navigator.getDisplayMedia === 'function' || (navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia === 'function')); -const getConferenceBridge = () => Meetings.findOne().voiceSettings.voiceConf; +const getConferenceBridge = () => getVoiceConf(); const normalizeGetDisplayMediaError = (error) => { return SCREENSHARING_ERRORS[error.name] || SCREENSHARING_ERRORS.GetDisplayMediaGenericError; @@ -37,6 +22,10 @@ const getBoundGDM = () => { } const getScreenStream = async () => { + const { + constraints: GDM_CONSTRAINTS, + } = window.meetingClientSettings.public.kurento.screenshare; + const gDMCallback = (stream) => { // Some older Chromium variants choke on gDM when audio: true by NOT generating // a promise rejection AND not generating a valid input screen stream, need to @@ -107,10 +96,21 @@ const getIceServers = (sessionToken) => { } const getMediaServerAdapter = () => { + const { + mediaServer: DEFAULT_SCREENSHARE_MEDIA_SERVER, + } = window.meetingClientSettings.public.kurento.screenshare; return getFromMeetingSettings('media-server-screenshare', DEFAULT_SCREENSHARE_MEDIA_SERVER); } const getNextReconnectionInterval = (oldInterval) => { + const { + mediaTimeouts: MEDIA_TIMEOUTS, + } = window.meetingClientSettings.public.kurento.screenshare; + const { + maxTimeout: MAX_MEDIA_TIMEOUT, + timeoutIncreaseFactor: TIMEOUT_INCREASE_FACTOR, + baseReconnectionTimeout: BASE_RECONNECTION_TIMEOUT, + } = MEDIA_TIMEOUTS; return Math.min( (TIMEOUT_INCREASE_FACTOR * Math.max(oldInterval, BASE_RECONNECTION_TIMEOUT)), MAX_MEDIA_TIMEOUT, @@ -148,6 +148,45 @@ const screenshareLoadAndPlayMediaStream = (stream, mediaElement, muted) => { }); } +class EXPORTED_CONFIGS { + static BASE_MEDIA_TIMEOUT() { + const { + mediaTimeouts: MEDIA_TIMEOUTS, + } = window.meetingClientSettings.public.kurento.screenshare; + const { + baseTimeout: BASE_MEDIA_TIMEOUT, + } = MEDIA_TIMEOUTS; + return BASE_MEDIA_TIMEOUT; + } + + static BASE_RECONNECTION_TIMEOUT() { + const { + mediaTimeouts: MEDIA_TIMEOUTS, + } = window.meetingClientSettings.public.kurento.screenshare; + const { + baseReconnectionTimeout: BASE_RECONNECTION_TIMEOUT, + } = MEDIA_TIMEOUTS; + return BASE_RECONNECTION_TIMEOUT; + } + + static MAX_CONN_ATTEMPTS() { + const { + mediaTimeouts: MEDIA_TIMEOUTS, + } = window.meetingClientSettings.public.kurento.screenshare; + const { + maxConnectionAttempts: MAX_CONN_ATTEMPTS, + } = MEDIA_TIMEOUTS; + return MAX_CONN_ATTEMPTS; + } + + static BASE_BITRATE() { + const { + bitrate: BASE_BITRATE, + } = window.meetingClientSettings.public.kurento.screenshare; + return BASE_BITRATE; + } +} + export default { HAS_DISPLAY_MEDIA, getConferenceBridge, @@ -157,8 +196,8 @@ export default { streamHasAudioTrack, screenshareLoadAndPlayMediaStream, getMediaServerAdapter, - BASE_MEDIA_TIMEOUT, - BASE_RECONNECTION_TIMEOUT, - MAX_CONN_ATTEMPTS, - BASE_BITRATE, + BASE_MEDIA_TIMEOUT: EXPORTED_CONFIGS.BASE_MEDIA_TIMEOUT, + BASE_RECONNECTION_TIMEOUT: EXPORTED_CONFIGS.BASE_RECONNECTION_TIMEOUT, + MAX_CONN_ATTEMPTS: EXPORTED_CONFIGS.MAX_CONN_ATTEMPTS, + BASE_BITRATE: EXPORTED_CONFIGS.BASE_BITRATE, }; diff --git a/bigbluebutton-html5/imports/api/screenshare/index.js b/bigbluebutton-html5/imports/api/screenshare/index.js deleted file mode 100644 index fc380b23ac..0000000000 --- a/bigbluebutton-html5/imports/api/screenshare/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -const collectionOptions = Meteor.isClient ? { - connection: null, -} : {}; - -const Screenshare = new Mongo.Collection('screenshare', collectionOptions); - -if (Meteor.isServer) { - // types of queries for the screenshare: - // 1. meetingId - - Screenshare.createIndexAsync({ meetingId: 1 }); -} - -export default Screenshare; diff --git a/bigbluebutton-html5/imports/api/timer/index.js b/bigbluebutton-html5/imports/api/timer/index.js deleted file mode 100644 index c43d8e33c4..0000000000 --- a/bigbluebutton-html5/imports/api/timer/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -const Timer = new Mongo.Collection('timer'); - -if (Meteor.isServer) { - Timer.createIndex({ meetingId: 1 }); -} - -export default Timer; diff --git a/bigbluebutton-html5/imports/api/users/index.js b/bigbluebutton-html5/imports/api/users/index.js deleted file mode 100644 index 03f6427bcf..0000000000 --- a/bigbluebutton-html5/imports/api/users/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -const collectionOptions = Meteor.isClient ? { - connection: null, -} : {}; - -const Users = new Mongo.Collection('users', collectionOptions); - -if (Meteor.isServer) { - // types of queries for the users: - // 1. meetingId - // 2. meetingId, userId - // { connection: Meteor.isClient ? null : true } - Users.createIndexAsync({ meetingId: 1, userId: 1 }); -} - -export default Users; diff --git a/bigbluebutton-html5/imports/api/video-streams/index.js b/bigbluebutton-html5/imports/api/video-streams/index.js deleted file mode 100644 index b997043bd8..0000000000 --- a/bigbluebutton-html5/imports/api/video-streams/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -const collectionOptions = Meteor.isClient ? { - connection: null, -} : {}; - -const VideoStreams = new Mongo.Collection('video-streams', collectionOptions); - -if (Meteor.isServer) { - // types of queries for the video users: - // 2. meetingId - - VideoStreams.createIndexAsync({ meetingId: 1 }); -} - -export default VideoStreams; diff --git a/bigbluebutton-html5/imports/api/voice-users/index.js b/bigbluebutton-html5/imports/api/voice-users/index.js deleted file mode 100644 index 2bfa16112f..0000000000 --- a/bigbluebutton-html5/imports/api/voice-users/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -const collectionOptions = Meteor.isClient ? { - connection: null, -} : {}; - -const VoiceUsers = new Mongo.Collection('voiceUsers', collectionOptions); - -if (Meteor.isServer) { - // types of queries for the voice users: - // 1. intId - // 2. meetingId, intId - - VoiceUsers.createIndexAsync({ intId: 1 }); - VoiceUsers.createIndexAsync({ meetingId: 1, intId: 1 }); -} - -export default VoiceUsers; diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx index db2eb7930b..0163c897eb 100755 --- a/bigbluebutton-html5/imports/startup/client/base.jsx +++ b/bigbluebutton-html5/imports/startup/client/base.jsx @@ -1,38 +1,24 @@ import React, { Component } from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; -import PropTypes from 'prop-types'; import Auth from '/imports/ui/services/auth'; import AppContainer from '/imports/ui/components/app/container'; -import LoadingScreen from '/imports/ui/components/common/loading-screen/component'; -import Settings from '/imports/ui/services/settings'; -import logger from '/imports/startup/client/logger'; -import { Session } from 'meteor/session'; -import { Meteor } from 'meteor/meteor'; -import AppService from '/imports/ui/components/app/service'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; +import Session from '/imports/ui/services/storage/in-memory'; import deviceInfo from '/imports/utils/deviceInfo'; import getFromUserSettings from '/imports/ui/services/users-settings'; import { layoutSelectInput, layoutDispatch } from '../../ui/components/layout/context'; -import { useVideoStreams } from '/imports/ui/components/video-provider/video-provider-graphql/hooks'; +import { useVideoStreams } from '/imports/ui/components/video-provider/hooks'; import DebugWindow from '/imports/ui/components/debug-window/component'; import { ACTIONS, PANELS } from '../../ui/components/layout/enums'; -import { isChatEnabled } from '/imports/ui/services/features'; +import { useIsChatEnabled } from '/imports/ui/services/features'; import useUserChangedLocalSettings from '/imports/ui/services/settings/hooks/useUserChangedLocalSettings'; - -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_CHAT_ID = CHAT_CONFIG.public_group_id; +import useSettings from '/imports/ui/services/settings/hooks/useSettings'; +import { SETTINGS } from '/imports/ui/services/settings/enums'; +import { useStorageKey } from '/imports/ui/services/storage/hooks'; const HTML = document.getElementsByTagName('html')[0]; let checkedUserSettings = false; -const propTypes = { - approved: PropTypes.bool, -}; - -const defaultProps = { - approved: false, -}; - const fullscreenChangedEvents = [ 'fullscreenchange', 'webkitfullscreenchange', @@ -54,7 +40,7 @@ class Base extends Component { || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement) { - Session.set('isFullscreen', true); + Session.setItem('isFullscreen', true); } else { layoutContextDispatch({ type: ACTIONS.SET_FULLSCREEN_ELEMENT, @@ -63,12 +49,13 @@ class Base extends Component { group: '', }, }); - Session.set('isFullscreen', false); + Session.setItem('isFullscreen', false); } } componentDidMount() { const { animations, usersVideo, layoutContextDispatch } = this.props; + const CAPTIONS_ALWAYS_VISIBLE = window.meetingClientSettings.public.app.audioCaptions.alwaysVisible; layoutContextDispatch({ type: ACTIONS.SET_NUM_CAMERAS, @@ -81,7 +68,8 @@ class Base extends Component { fullscreenChangedEvents.forEach((event) => { document.addEventListener(event, this.handleFullscreenChange); }); - Session.set('isFullscreen', false); + Session.setItem('isFullscreen', false); + Session.setItem('audioCaptions', CAPTIONS_ALWAYS_VISIBLE); } componentDidUpdate(prevProps) { @@ -91,6 +79,7 @@ class Base extends Component { sidebarContentPanel, usersVideo, setLocalSettings, + isChatEnabled, } = this.props; if (usersVideo !== prevProps.usersVideo) { @@ -118,11 +107,14 @@ class Base extends Component { window.meetingClientSettings.public.app.defaultSettings.application.animations ); + const Settings = getSettingsSingletonInstance(); Settings.application.animations = showAnimationsDefault; Settings.save(setLocalSettings); if (getFromUserSettings('bbb_show_participants_on_login', window.meetingClientSettings.public.layout.showParticipantsOnLogin) && !deviceInfo.isPhone) { - if (isChatEnabled() && getFromUserSettings('bbb_show_public_chat_on_login', !window.meetingClientSettings.public.chat.startClosed)) { + if (isChatEnabled && getFromUserSettings('bbb_show_public_chat_on_login', !window.meetingClientSettings.public.chat.startClosed)) { + const PUBLIC_CHAT_ID = window.meetingClientSettings.public.chat.public_group_id; + layoutContextDispatch({ type: ACTIONS.SET_SIDEBAR_NAVIGATION_IS_OPEN, value: true, @@ -181,19 +173,20 @@ class Base extends Component { } } -Base.propTypes = propTypes; -Base.defaultProps = defaultProps; - const BaseContainer = (props) => { + const codeError = useStorageKey('codeError'); const sidebarContent = layoutSelectInput((i) => i.sidebarContent); const { sidebarContentPanel } = sidebarContent; const layoutContextDispatch = layoutDispatch(); const setLocalSettings = useUserChangedLocalSettings(); - const { streams: usersVideo } = useVideoStreams( - props.isGridLayout, - props.paginationEnabled, - props.viewParticipantsWebcams, - ); + + const applicationSettings = useSettings(SETTINGS.APPLICATION); + const animations = applicationSettings?.animations; + + const { viewScreenshare } = useSettings(SETTINGS.DATA_SAVING); + const { streams: usersVideo } = useVideoStreams(); + const loggedIn = Auth.useLoggedIn(); + const isChatEnabled = useIsChatEnabled(); return ( { layoutContextDispatch, setLocalSettings, usersVideo, + animations, + viewScreenshare, + codeError, + loggedIn, + isChatEnabled, ...props, }} /> ); }; -export default withTracker(() => { - const { - animations, - } = Settings.application; - - const { - loggedIn, - } = Auth; - - let userSubscriptionHandler; - - const codeError = Session.get('codeError'); - const isGridLayout = Session.get('isGridEnabled'); - return { - userSubscriptionHandler, - animations, - isMeteorConnected: Meteor.status().connected, - meetingIsBreakout: AppService.meetingIsBreakout(), - loggedIn, - codeError, - paginationEnabled: Settings.application.paginationEnabled, - viewParticipantsWebcams: Settings.dataSaving.viewParticipantsWebcams, - isGridLayout, - }; -})(BaseContainer); +export default BaseContainer; diff --git a/bigbluebutton-html5/imports/startup/client/intlAdapter.tsx b/bigbluebutton-html5/imports/startup/client/intlAdapter.tsx index e6d90644a9..d0ad1d0032 100644 --- a/bigbluebutton-html5/imports/startup/client/intlAdapter.tsx +++ b/bigbluebutton-html5/imports/startup/client/intlAdapter.tsx @@ -1,17 +1,20 @@ import React, { useContext, useEffect } from 'react'; import { useIntl } from 'react-intl'; import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; -import Settings from '/imports/ui/services/settings'; -import { Session } from 'meteor/session'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; +import Session from '/imports/ui/services/storage/in-memory'; import { formatLocaleCode } from '/imports/utils/string-utils'; -import Intl from '/imports/ui/services/locale'; import useCurrentLocale from '/imports/ui/core/local-states/useCurrentLocale'; import { LoadingContext } from '/imports/ui/components/common/loading-screen/loading-screen-HOC/component'; import { UI_DATA_LISTENER_SUBSCRIBED } from 'bigbluebutton-html-plugin-sdk/dist/cjs/ui-data-hooks/consts'; +import intlHolder from '/imports/ui/core/singletons/intlHolder'; +import useUserChangedLocalSettings from '/imports/ui/services/settings/hooks/useUserChangedLocalSettings'; +import { localUserSettings } from '/imports/ui/core/local-states/useUserSettings'; +import { layoutDispatch } from '/imports/ui/components/layout/context'; +import { ACTIONS } from '/imports/ui/components/layout/enums'; const RTL_LANGUAGES = ['ar', 'dv', 'fa', 'he']; const LARGE_FONT_LANGUAGES = ['te', 'km']; -const DEFAULT_LANGUAGE = window.meetingClientSettings.public.app.defaultSettings.application.fallbackLocale; interface IntlAdapterProps { children: React.ReactNode; @@ -20,9 +23,19 @@ interface IntlAdapterProps { const IntlAdapter: React.FC = ({ children, }) => { + const Settings = getSettingsSingletonInstance(); const [currentLocale, setCurrentLocale] = useCurrentLocale(); const intl = useIntl(); const loadingContextInfo = useContext(LoadingContext); + const setLocalSettings = useUserChangedLocalSettings(); + const layoutContextDispatch = layoutDispatch(); + + const DEFAULT_LANGUAGE = window.meetingClientSettings.public.app.defaultSettings.application.fallbackLocale; + + useEffect(() => { + intlHolder.setIntl(intl); + }, [currentLocale]); + const sendUiDataToPlugins = () => { window.dispatchEvent(new CustomEvent(PluginSdk.IntlLocaleUiDataNames.CURRENT_LOCALE, { detail: { @@ -36,22 +49,29 @@ const IntlAdapter: React.FC = ({ const { language, formattedLocale } = formatLocaleCode(currentLocale); // @ts-ignore - JS code Settings.application.locale = currentLocale; - Intl.setLocale(formattedLocale, intl.messages); if (RTL_LANGUAGES.includes(currentLocale.substring(0, 2))) { // @ts-ignore - JS code document.body.parentNode.setAttribute('dir', 'rtl'); // @ts-ignore - JS code Settings.application.isRTL = true; + layoutContextDispatch({ + type: ACTIONS.SET_IS_RTL, + value: true, + }); } else { // @ts-ignore - JS code document.body.parentNode.setAttribute('dir', 'ltr'); // @ts-ignore - JS code Settings.application.isRTL = false; + layoutContextDispatch({ + type: ACTIONS.SET_IS_RTL, + value: false, + }); } - Session.set('isLargeFont', LARGE_FONT_LANGUAGES.includes(currentLocale.substring(0, 2))); + Session.setItem('isLargeFont', LARGE_FONT_LANGUAGES.includes(currentLocale.substring(0, 2))); document.getElementsByTagName('html')[0].lang = formattedLocale; document.body.classList.add(`lang-${language}`); - Settings.save(); + Settings.save(setLocalSettings); } }; const runOnMountAndUnmount = () => { @@ -61,11 +81,16 @@ const IntlAdapter: React.FC = ({ ); // @ts-ignore - JS code const { locale } = Settings.application; - if ( + const clientSettings = window.meetingClientSettings.public.app.defaultSettings.application; + const { overrideLocale } = clientSettings; + const { bbb_override_default_locale } = localUserSettings(); + if (typeof bbb_override_default_locale === 'string') { + setCurrentLocale(bbb_override_default_locale); + } else if ( typeof locale === 'string' && locale !== currentLocale ) { - setCurrentLocale(locale); + setCurrentLocale(overrideLocale || locale); } else { setUp(); } @@ -80,6 +105,14 @@ const IntlAdapter: React.FC = ({ const runOnCurrentLocaleUpdate = () => { setUp(); sendUiDataToPlugins(); + window.removeEventListener( + `${UI_DATA_LISTENER_SUBSCRIBED}-${PluginSdk.IntlLocaleUiDataNames.CURRENT_LOCALE}`, + sendUiDataToPlugins, + ); + window.addEventListener( + `${UI_DATA_LISTENER_SUBSCRIBED}-${PluginSdk.IntlLocaleUiDataNames.CURRENT_LOCALE}`, + sendUiDataToPlugins, + ); }; useEffect(runOnMountAndUnmount, []); diff --git a/bigbluebutton-html5/imports/startup/client/intlLoader.tsx b/bigbluebutton-html5/imports/startup/client/intlLoader.tsx index e6975a919e..87e0b82877 100644 --- a/bigbluebutton-html5/imports/startup/client/intlLoader.tsx +++ b/bigbluebutton-html5/imports/startup/client/intlLoader.tsx @@ -20,7 +20,7 @@ interface IntlLoaderProps extends IntlLoaderContainerProps { const buildFetchLocale = (locale: string) => { const localesPath = 'locales'; return new Promise((resolve) => { - fetch(`${localesPath}/${locale}.json`) + fetch(`${localesPath}/${locale !== 'index' ? `${locale}.json` : ''}`) .then((response) => { if (!response.ok) { return resolve(false); @@ -36,12 +36,11 @@ const buildFetchLocale = (locale: string) => { }; const fetchLocaleOptions = (locale: string, init: boolean, localesList: string[] = []) => { - const clientSettings = JSON.parse(sessionStorage.getItem('clientStartupSettings') || '{}'); - const fallback = clientSettings.fallbackLocale; - const override = clientSettings.overrideLocale; + const clientSettings = window.meetingClientSettings.public; + const { fallbackLocale: fallback, overrideLocale: override } = clientSettings.app.defaultSettings.application; const browserLocale = override && init ? override.split(/[-_]/g) : locale.split(/[-_]/g); - const defaultLanguage = clientSettings.fallbackLocale; - const fallbackOnEmptyString = clientSettings.fallbackOnEmptyLocaleString; + const defaultLanguage = fallback; + const fallbackOnEmptyString = clientSettings.app.fallbackOnEmptyLocaleString; let localeFile = fallback; let normalizedLocale: string = ''; @@ -102,7 +101,11 @@ const IntlLoader: React.FC = ({ setFetching(true); buildFetchLocale('index') .then((resp) => { - const data = fetchLocaleOptions(locale, init, resp as string[]); + const data = fetchLocaleOptions( + locale, + init, + (resp as { name: string }[]).map((l) => l.name), + ); const { defaultLocale, diff --git a/bigbluebutton-html5/imports/startup/client/logger.js b/bigbluebutton-html5/imports/startup/client/logger.js deleted file mode 100755 index 67cbe648e5..0000000000 --- a/bigbluebutton-html5/imports/startup/client/logger.js +++ /dev/null @@ -1,163 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { createLogger, stdSerializers } from 'browser-bunyan'; -import { ConsoleFormattedStream } from '@browser-bunyan/console-formatted-stream'; -import { ConsoleRawStream } from '@browser-bunyan/console-raw-stream'; -import { ServerStream } from '@browser-bunyan/server-stream'; -import { nameFromLevel } from '@browser-bunyan/levels'; - -// The logger accepts "console","server", and "external" as targets -// Multiple targets can be set as an array in the settings under public.log -// To add more targets use the format { "target": "server", "level": "info" }, -// and add it to the public.log array -// The accepted levels are "debug", "info", "warn", "error" -// To send to URL, use the format {"target": "external","level": "info", -// "url": "","method": ""} -// externalURL is the end-point that logs will be sent to -// Call the logger by doing a function call with the level name, I.e, logger.warn('Hi on warn') -const fallback = { console: { enabled: true, level: 'info' } }; -const LOG_CONFIG = (JSON.parse(sessionStorage.getItem('clientStartupSettings') || '{}')?.clientLog) || fallback; - -export function createStreamForTarget(target, options) { - const TARGET_EXTERNAL = 'external'; - const TARGET_CONSOLE = 'console'; - const TARGET_SERVER = 'server'; - - let Stream = ConsoleRawStream; - switch (target) { - case TARGET_EXTERNAL: - Stream = ServerLoggerStream; - break; - case TARGET_CONSOLE: - Stream = ConsoleFormattedStream; - break; - case TARGET_SERVER: - Stream = MeteorStream; - break; - default: - Stream = ConsoleFormattedStream; - } - - return new Stream(options); -} - -export function generateLoggerStreams(config) { - let result = []; - Object.keys(config).forEach((key) => { - const logOption = config[key]; - if (logOption && logOption.enabled) { - const { level, ...streamOptions } = logOption; - result = result.concat({ level, stream: createStreamForTarget(key, streamOptions) }); - } - }); - return result; -} - -// Custom stream that logs to an end-point -class ServerLoggerStream extends ServerStream { - constructor(params) { - super(params); - - if (params.logTag) { - this.logTagString = params.logTag; - } - this.auth = null; - } - - setConfig(config) { - const streams = generateLoggerStreams(config); - const { addStream } = this; - streams.forEach((stream) => { - addStream(stream); - }); - } - - setAuth(auth) { - this.auth = auth; - } - - getUserData() { - let userInfo = {}; - if (this.auth) { - userInfo = this.auth.fullInfo; - } else { - userInfo = { - meetingId: sessionStorage.getItem('meetingId'), - userId: sessionStorage.getItem('userId'), - logoutUrl: sessionStorage.getItem('logoutUrl'), - sessionToken: sessionStorage.getItem('sessionToken'), - userName: sessionStorage.getItem('userName'), - extId: sessionStorage.getItem('extId'), - meetingName: sessionStorage.getItem('meetingName'), - }; - } - - if (userInfo.meetingId) { - userInfo = { - sessionToken: sessionStorage.getItem('sessionToken'), - }; - } - - return { - fullInfo: userInfo, - }; - } - - write(rec) { - const { fullInfo } = this.getUserData(); - - this.rec = rec; - if (fullInfo.meetingId != null) { - this.rec.userInfo = fullInfo; - } - this.rec.clientBuild = window.meetingClientSettings?.public?.app?.html5ClientBuild; - this.rec.connectionId = Meteor?.connection?._lastSessionId; - if (this.logTagString) { - this.rec.logTag = this.logTagString; - } - return super.write(this.rec); - } -} - -// Custom stream to log to the meteor server -class MeteorStream { - write(rec) { - const { fullInfo } = this.getUserData(); - const clientURL = window.location.href; - - this.rec = rec; - if (fullInfo.meetingId != null) { - if (!this.rec.extraInfo) { - this.rec.extraInfo = {}; - } - - this.rec.extraInfo.clientURL = clientURL; - - Meteor.call( - 'logClient', - nameFromLevel[this.rec.level], - this.rec.msg, - this.rec.logCode, - this.rec.extraInfo, - fullInfo, - ); - } else { - Meteor.call( - 'logClient', - nameFromLevel[this.rec.level], - this.rec.msg, - this.rec.logCode, - { ...rec.extraInfo, clientURL }, - ); - } - } -} - -// Creates the logger with the array of streams of the chosen targets -const logger = createLogger({ - name: 'clientLogger', - streams: generateLoggerStreams(LOG_CONFIG), - serializers: stdSerializers, - src: true, -}); - -export default logger; diff --git a/bigbluebutton-html5/imports/startup/client/logger/ServerStream.ts b/bigbluebutton-html5/imports/startup/client/logger/ServerStream.ts new file mode 100644 index 0000000000..61473a917f --- /dev/null +++ b/bigbluebutton-html5/imports/startup/client/logger/ServerStream.ts @@ -0,0 +1,60 @@ +import { ServerStream } from '@browser-bunyan/server-stream'; +import Auth from '/imports/ui/services/auth'; + +// Custom stream that logs to an end-point +export default class ServerLoggerStream extends ServerStream { + private logTagString: string | null = null; + + private rec: Record | null = null; + + constructor(params: { + enabled: boolean; + url?: string; + method?: string; + throttleInterval?: number; + flushOnClose?: boolean; + logTag?: string; + }) { + super(params); + + if (params.logTag) { + this.logTagString = params.logTag; + } + } + + static getUserData() { + let userInfo: Record = { + meetingId: Auth.meetingID, + userId: Auth.userID, + logoutUrl: Auth.logoutURL, + sessionToken: Auth.sessionToken, + userName: Auth.fullname, + extId: Auth.externUserID, + meetingName: Auth.confname, + }; + + if (userInfo.meetingId) { + userInfo = { + sessionToken: sessionStorage.getItem('sessionToken'), + }; + } + + return { + fullInfo: userInfo, + }; + } + + write(rec: Record) { + const { fullInfo } = ServerLoggerStream.getUserData(); + + this.rec = rec; + if (fullInfo.meetingId != null) { + this.rec.userInfo = fullInfo; + } + this.rec.clientBuild = window.meetingClientSettings?.public?.app?.html5ClientBuild; + if (this.logTagString) { + this.rec.logTag = this.logTagString; + } + return super.write(this.rec); + } +} diff --git a/bigbluebutton-html5/imports/startup/client/logger/index.ts b/bigbluebutton-html5/imports/startup/client/logger/index.ts new file mode 100644 index 0000000000..e9cb070005 --- /dev/null +++ b/bigbluebutton-html5/imports/startup/client/logger/index.ts @@ -0,0 +1,91 @@ +import { createLogger, Logger, stdSerializers } from 'browser-bunyan'; +import { ConsoleFormattedStream } from '@browser-bunyan/console-formatted-stream'; +import { ConsoleRawStream } from '@browser-bunyan/console-raw-stream'; +import { ClientLog } from '/imports/ui/Types/meetingClientSettings'; +import ServerLoggerStream from './ServerStream'; +import meetingClientSettingsInitialValues from '/imports/ui/core/initial-values/meetingClientSettings'; + +// The logger accepts "console","server", and "external" as targets +// Multiple targets can be set as an array in the settings under public.log +// To add more targets use the format { "target": "server", "level": "info" }, +// and add it to the public.log array +// The accepted levels are "debug", "info", "warn", "error" +// To send to URL, use the format {"target": "external","level": "info", +// "url": "","method": ""} +// externalURL is the end-point that logs will be sent to +// Call the logger by doing a function call with the level name, I.e, logger.warn('Hi on warn') +const FALLBACK_CONFIG = meetingClientSettingsInitialValues.public.clientLog; + +export function createStreamForTarget( + target: keyof ClientLog, + options: { + enabled: boolean; + url?: string; + method?: string; + throttleInterval?: number; + flushOnClose?: boolean; + logTag?: string; + }, +) { + const TARGET_EXTERNAL = 'external'; + const TARGET_CONSOLE = 'console'; + + let Stream; + switch (target) { + case TARGET_EXTERNAL: + Stream = ServerLoggerStream; + break; + case TARGET_CONSOLE: + Stream = ConsoleFormattedStream; + break; + default: + Stream = ConsoleFormattedStream; + } + + return new Stream(options); +} + +export function generateLoggerStreams(config: ClientLog) { + let result: { + level: string; + stream: ConsoleRawStream | ServerLoggerStream, + }[] = []; + Object.keys(config).forEach((key) => { + const logOption = config[key as keyof ClientLog]; + if (logOption && logOption.enabled) { + const { level, ...streamOptions } = logOption; + result = result.concat({ level, stream: createStreamForTarget(key as keyof ClientLog, streamOptions) }); + } + }); + return result; +} + +class BBBClientLogger { + private static fallback: Logger | null = null; + + private static default: Logger | null = null; + + public static get logger() { + if (BBBClientLogger.default) return BBBClientLogger.default; + const LOG_CONFIG = window.meetingClientSettings?.public?.clientLog; + if (LOG_CONFIG && !BBBClientLogger.default) { + BBBClientLogger.default = createLogger({ + name: 'clientLogger', + streams: generateLoggerStreams(LOG_CONFIG), + serializers: stdSerializers, + src: true, + }); + } + if (!BBBClientLogger.fallback) { + BBBClientLogger.fallback = createLogger({ + name: 'clientLogger', + streams: generateLoggerStreams(FALLBACK_CONFIG), + serializers: stdSerializers, + src: true, + }); + } + return BBBClientLogger.fallback; + } +} + +export default BBBClientLogger.logger; diff --git a/bigbluebutton-html5/imports/startup/server/ClientConnections.js b/bigbluebutton-html5/imports/startup/server/ClientConnections.js deleted file mode 100644 index 3dd979f401..0000000000 --- a/bigbluebutton-html5/imports/startup/server/ClientConnections.js +++ /dev/null @@ -1,172 +0,0 @@ -import Logger from './logger'; -import userLeaving from '/imports/api/users/server/methods/userLeaving'; -import { extractCredentials } from '/imports/api/common/server/helpers'; -import Users from '/imports/api/users'; -import { check } from 'meteor/check'; - -const { enabled, syncInterval } = Meteor.settings.public.syncUsersWithConnectionManager; - -class ClientConnections { - constructor() { - Logger.debug('Initializing client connections structure', { logCode: 'client_connections_init' }); - this.connections = new Map(); - - setInterval(() => { - this.print(); - }, 30000); - - if (enabled) { - const syncConnections = Meteor.bindEnvironment(() => { - this.syncConnectionsWithServer(); - }); - - setInterval(() => { - syncConnections(); - }, syncInterval); - } - } - - add(sessionId, connection) { - Logger.info('Client connections add called', { logCode: 'client_connections_add', extraInfo: { sessionId, connection } }); - if (!sessionId || !connection) { - Logger.error(`Error on add new client connection. sessionId=${sessionId} connection=${connection.id}`, - { logCode: 'client_connections_add_error', extraInfo: { sessionId, connection } } - ); - - return; - } - - const { meetingId, requesterUserId: userId } = extractCredentials(sessionId); - - check(meetingId, String); - check(userId, String); - - if (!meetingId) { - Logger.error(`Error on add new client connection. sessionId=${sessionId} connection=${connection.id}`, - { logCode: 'client_connections_add_error_meeting_id_null', extraInfo: { meetingId, userId } } - ); - return false; - } - - if (!this.exists(meetingId)) { - Logger.info(`Meeting not found in connections: meetingId=${meetingId}`); - this.createMeetingConnections(meetingId); - } - - const sessionConnections = this.connections.get(meetingId); - - if (sessionConnections.has(userId) && sessionConnections.get(userId).includes(connection.id)) { - Logger.info(`Connection already exists for user. userId=${userId} connectionId=${connection.id}`); - - return false; - } - - connection.onClose(Meteor.bindEnvironment(() => { - userLeaving(meetingId, userId, connection.id); - })); - - Logger.info(`Adding new connection for sessionId=${sessionId} connection=${connection.id}`); - - if (!sessionConnections.has(userId)) { - Logger.info(`Creating connections poll for ${userId}`); - - sessionConnections.set(userId, []); - return sessionConnections.get(userId).push(connection.id); - } else { - return sessionConnections.get(userId).push(connection.id); - } - } - - createMeetingConnections(meetingId) { - Logger.info(`Creating meeting in connections. meetingId=${meetingId}`); - - if (!this.exists(meetingId)) - return this.connections.set(meetingId, new Map()); - } - - exists(meetingId) { - return this.connections.has(meetingId); - } - - getConnectionsForClient(sessionId) { - const { meetingId, requesterUserId: userId } = extractCredentials(sessionId); - - check(meetingId, String); - check(userId, String); - - return this.connections.get(meetingId)?.get(userId); - } - - print() { - const mapConnectionsObj = {}; - this.connections.forEach((value, key) => { - mapConnectionsObj[key] = {}; - - value.forEach((v, k) => { - mapConnectionsObj[key][k] = v; - }); - - }); - Logger.info('Active connections', mapConnectionsObj); - } - - removeClientConnection(sessionId, connectionId = null) { - Logger.info(`Removing connectionId for user. sessionId=${sessionId} connectionId=${connectionId}`); - const { meetingId, requesterUserId: userId } = extractCredentials(sessionId); - - check(meetingId, String); - check(userId, String); - - const meetingConnections = this.connections.get(meetingId); - - if (meetingConnections?.has(userId)) { - const filteredConnections = meetingConnections.get(userId).filter(c => c !== connectionId); - - return connectionId && filteredConnections.length ? meetingConnections.set(userId, filteredConnections) : meetingConnections.delete(userId); - } - - return false; - } - - removeMeeting(meetingId) { - Logger.debug(`Removing connections for meeting=${meetingId}`); - return this.connections.delete(meetingId); - } - - syncConnectionsWithServer() { - Logger.info('Syncing ClientConnections with server'); - const activeConnections = Array.from(Meteor.server.sessions.keys()); - - Logger.debug(`Found ${activeConnections.length} active connections in server`); - - const onlineUsersId = onlineUsers.map(({ userId }) => userId); - - const usersQuery = { userId: { $nin: onlineUsersId } }; - - const userWithoutConnectionIds = Users.find(usersQuery, { fields: { meetingId: 1, userId: 1 } }).fetch(); - - const removedUsersWithoutConnection = Users.remove(usersQuery); - - if (removedUsersWithoutConnection) { - Logger.info(`Removed ${removedUsersWithoutConnection} users that are not connected`); - Logger.info(`Clearing connections`); - try { - userWithoutConnectionIds - .forEach(({ meetingId, userId }) => { - this.removeClientConnection(`${meetingId}--${userId}`); - }); - } catch (err) { - Logger.error('Error on sync ClientConnections', err); - } - } - } - -} - -if (!process.env.BBB_HTML5_ROLE || process.env.BBB_HTML5_ROLE === 'frontend') { - Logger.info("ClientConnectionsSingleton was created") - - const ClientConnectionsSingleton = new ClientConnections(); - - export default ClientConnectionsSingleton; -} diff --git a/bigbluebutton-html5/imports/startup/server/index.js b/bigbluebutton-html5/imports/startup/server/index.js deleted file mode 100755 index 2b3240fc5b..0000000000 --- a/bigbluebutton-html5/imports/startup/server/index.js +++ /dev/null @@ -1,370 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { WebAppInternals } from 'meteor/webapp'; -import Langmap from 'langmap'; -import fs from 'fs'; -import Users from '/imports/api/users'; -import './settings'; -import { check } from 'meteor/check'; -import Logger from './logger'; - -import setMinBrowserVersions from './minBrowserVersion'; -import { PrometheusAgent, METRIC_NAMES } from './prom-metrics/index.js' - -let guestWaitHtml = ''; - -const DEFAULT_LANGUAGE = Meteor.settings.public.app.defaultSettings.application.fallbackLocale; -const FALLBACK_ON_EMPTY_STRING = Meteor.settings.public.app.fallbackOnEmptyLocaleString; - -const env = Meteor.isDevelopment ? 'development' : 'production'; - -const meteorRoot = fs.realpathSync(`${process.cwd()}/../`); - -const applicationRoot = (env === 'development') - ? fs.realpathSync(`${meteorRoot}'/../../../../public/locales/`) - : fs.realpathSync(`${meteorRoot}/../programs/web.browser/app/locales/`); - -const AVAILABLE_LOCALES = fs.readdirSync(`${applicationRoot}`); -const FALLBACK_LOCALES = JSON.parse(Assets.getText('config/fallbackLocales.json')); - -process.on('uncaughtException', (err) => { - Logger.error(`uncaughtException: ${err}`); - process.exit(1); -}); - -const formatMemoryUsage = (data) => `${Math.round(data / 1024 / 1024 * 100) / 100} MB` - -const serverHealth = () => { - const memoryData = process.memoryUsage(); - const memoryUsage = { - rss: formatMemoryUsage(memoryData.rss), - heapTotal: formatMemoryUsage(memoryData.heapTotal), - heapUsed: formatMemoryUsage(memoryData.heapUsed), - external: formatMemoryUsage(memoryData.external), - } - - const cpuData = process.cpuUsage(); - const cpuUsage = { - system: formatMemoryUsage(cpuData.system), - user: formatMemoryUsage(cpuData.user), - } - - Logger.info('Server health', {memoryUsage, cpuUsage}); -}; - -Meteor.startup(() => { - const APP_CONFIG = Meteor.settings.public.app; - const CDN_URL = APP_CONFIG.cdn; - const instanceId = parseInt(process.env.INSTANCE_ID, 10) || 1; - - Logger.warn(`Started bbb-html5 process with instanceId=${instanceId}`); - - const LOG_CONFIG = Meteor.settings.private.serverLog; - const { healthChecker } = LOG_CONFIG; - const { enable: enableHealthCheck, intervalMs: healthCheckInterval } = healthChecker; - - if (enableHealthCheck) { - Meteor.setInterval(() => { - serverHealth(); - }, healthCheckInterval); - } - - const { customHeartbeat, customHeartbeatUseDataFrames } = APP_CONFIG; - - if (customHeartbeat) { - Logger.warn('Custom heartbeat functions are enabled'); - // https://github.com/sockjs/sockjs-node/blob/1ef08901f045aae7b4df0f91ef598d7a11e82897/lib/transport/websocket.js#L74-L82 - const heartbeatFactory = function ({ heartbeatTimeoutCallback }) { - return function () { - const currentTime = new Date().getTime(); - - if (customHeartbeatUseDataFrames) { - // Skipping heartbeat, because websocket is sending data - if (currentTime - this.ws.lastSentFrameTimestamp < 10000) { - try { - Logger.debug('Skipping heartbeat, because websocket is sending data', { - currentTime, - lastSentFrameTimestamp: this.ws.lastSentFrameTimestamp, - userId: this.session?.connection?._meteorSession?.userId, - }); - return; - } catch (err) { - Logger.error(`Skipping heartbeat error: ${err}`); - } - } - } - - const supportsHeartbeats = this.ws.ping(null, () => { - clearTimeout(this.hto_ref); - }); - - if (supportsHeartbeats) { - this.hto_ref = setTimeout(() => { - try { - Logger.warn('Heartbeat timeout', { userId: this.session?.connection?._meteorSession?.userId, sentAt: currentTime, now: new Date().getTime() }); - } catch (err) { - Logger.error(`Heartbeat timeout error: ${err}`); - } finally { - if (typeof heartbeatTimeoutCallback === 'function') { - heartbeatTimeoutCallback(); - } - } - }, Meteor.server.options.heartbeatTimeout); - } else { - Logger.error('Unexpected error supportsHeartbeats=false'); - } - }; - }; - - // https://github.com/davhani/hagty/blob/6a5c78e9ae5a5e4ade03e747fb4cc8ea2df4be0c/faye-websocket/lib/faye/websocket/api.js#L84-L88 - const newSend = function send(data) { - try { - this.lastSentFrameTimestamp = new Date().getTime(); - - if (this.meteorHeartbeat) { - // Call https://github.com/meteor/meteor/blob/1e7e56eec8414093cd0c1c70750b894069fc972a/packages/ddp-common/heartbeat.js#L80-L88 - this.meteorHeartbeat._seenPacket = true; - if (this.meteorHeartbeat._heartbeatTimeoutHandle) { - this.meteorHeartbeat._clearHeartbeatTimeoutTimer(); - } - } - - if (this.readyState > 1/* API.OPEN = 1 */) return false; - if (!(data instanceof Buffer)) data = String(data); - return this._driver.messages.write(data); - } catch (err) { - console.error('Error on send data', err); - return false; - } - }; - - Meteor.setInterval(() => { - for (const session of Meteor.server.sessions.values()) { - const { socket } = session; - const recv = socket._session.recv; - - if (session.bbbFixApplied || !recv || !recv.ws) { - continue; - } - - recv.ws.meteorHeartbeat = session.heartbeat; - recv.heartbeat = heartbeatFactory({ - heartbeatTimeoutCallback: recv.heartbeat_cb - }); - recv.ws.send = newSend; - session.bbbFixApplied = true; - } - }, 5000); - } - if (CDN_URL.trim()) { - // Add CDN - BrowserPolicy.content.disallowEval(); - BrowserPolicy.content.allowInlineScripts(); - BrowserPolicy.content.allowInlineStyles(); - BrowserPolicy.content.allowImageDataUrl(CDN_URL); - BrowserPolicy.content.allowFontDataUrl(CDN_URL); - BrowserPolicy.content.allowOriginForAll(CDN_URL); - WebAppInternals.setBundledJsCssPrefix(CDN_URL + APP_CONFIG.basename + Meteor.settings.public.app.instanceId); - - const fontRegExp = /\.(eot|ttf|otf|woff|woff2)$/; - - WebApp.rawConnectHandlers.use('/', (req, res, next) => { - if (fontRegExp.test(req._parsedUrl.pathname)) { - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Vary', 'Origin'); - res.setHeader('Pragma', 'public'); - res.setHeader('Cache-Control', '"public"'); - } - return next(); - }); - } - - setMinBrowserVersions(); - - Meteor.onMessage(event => { - const { method } = event; - if (method) { - const methodName = method.includes('stream-cursor') ? 'stream-cursor' : method; - PrometheusAgent.increment(METRIC_NAMES.METEOR_METHODS, { methodName }); - } - }); - - Logger.warn(`SERVER STARTED. - ENV=${env} - nodejs version=${process.version} - BBB_HTML5_ROLE=${process.env.BBB_HTML5_ROLE} - INSTANCE_ID=${instanceId} - PORT=${process.env.PORT} - CDN=${CDN_URL}\n`, APP_CONFIG); -}); - -const generateLocaleOptions = () => { - try { - Logger.warn('Calculating aggregateLocales (heavy)'); - - // remove duplicated locales (always remove more generic if same name) - const tempAggregateLocales = AVAILABLE_LOCALES - .map(file => file.replace('.json', '')) - .map(file => file.replace('_', '-')) - .map((locale) => { - const localeName = (Langmap[locale] || {}).nativeName - || (FALLBACK_LOCALES[locale] || {}).nativeName - || locale; - return { - locale, - name: localeName, - }; - }).reverse() - .filter((item, index, self) => index === self.findIndex(i => ( - i.name === item.name - ))) - .reverse(); - - Logger.warn(`Total locales: ${tempAggregateLocales.length}`, tempAggregateLocales); - - const filePath = `${applicationRoot}/index.json`; - const jsContent = JSON.stringify(AVAILABLE_LOCALES, null, 2); - - // Write JSON data to a file - fs.writeFile(filePath, jsContent, (err) => { - if (err) { - Logger.error('Error writing file:', err); - } else { - Logger.info(`JSON data has been written to ${filePath}`); - } - }); - - return tempAggregateLocales; - } catch (e) { - Logger.error(`'Could not process locales error: ${e}`); - return []; - } -}; - -let avaibleLocalesNamesJSON = JSON.stringify(generateLocaleOptions()); - -WebApp.connectHandlers.use('/check', (req, res) => { - const payload = { html5clientStatus: 'running' }; - - res.setHeader('Content-Type', 'application/json'); - res.writeHead(200); - res.end(JSON.stringify(payload)); -}); - -WebApp.connectHandlers.use('/locale', (req, res) => { - const APP_CONFIG = Meteor.settings.public.app; - const fallback = APP_CONFIG.defaultSettings.application.fallbackLocale; - const override = APP_CONFIG.defaultSettings.application.overrideLocale; - const browserLocale = override && req.query.init === 'true' - ? override.split(/[-_]/g) : req.query.locale.split(/[-_]/g); - - let localeFile = fallback; - - const usableLocales = AVAILABLE_LOCALES - .map(file => file.replace('.json', '')) - .reduce((locales, locale) => (locale.match(browserLocale[0]) - ? [...locales, locale] - : locales), []); - - let normalizedLocale; - - const regionDefault = usableLocales.find(locale => browserLocale[0] === locale); - - if (browserLocale.length > 1) { - // browser asks for specific locale - normalizedLocale = `${browserLocale[0]}_${browserLocale[1]?.toUpperCase()}`; - - const normDefault = usableLocales.find(locale => normalizedLocale === locale); - if (normDefault) { - localeFile = normDefault; - } else { - if (regionDefault) { - localeFile = regionDefault; - } else { - const specFallback = usableLocales.find(locale => browserLocale[0] === locale.split("_")[0]); - if (specFallback) localeFile = specFallback; - } - } - } else { - // browser asks for region default locale - if (regionDefault && localeFile === fallback && regionDefault !== localeFile) { - localeFile = regionDefault; - } else { - const normFallback = usableLocales.find(locale => browserLocale[0] === locale.split("_")[0]); - if (normFallback) localeFile = normFallback; - } - } - - res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ - normalizedLocale: localeFile, - regionDefaultLocale: (regionDefault && regionDefault !== localeFile) ? regionDefault : '', - defaultLocale: DEFAULT_LANGUAGE, - fallbackOnEmptyLocaleString: FALLBACK_ON_EMPTY_STRING, - })); -}); - -WebApp.connectHandlers.use('/locale-list', (req, res) => { - if (!avaibleLocalesNamesJSON) { - avaibleLocalesNamesJSON = JSON.stringify(generateLocaleOptions()); - } - - res.setHeader('Content-Type', 'application/json'); - res.writeHead(200); - res.end(avaibleLocalesNamesJSON); -}); - -WebApp.connectHandlers.use('/feedback', (req, res) => { - req.on('data', Meteor.bindEnvironment((data) => { - const body = JSON.parse(data); - const { - meetingId, - userId, - authToken, - userName: reqUserName, - comment, - rating, - } = body; - - check(meetingId, String); - check(userId, String); - check(authToken, String); - check(reqUserName, String); - check(comment, String); - check(rating, Number); - - const user = Users.findOne({ - meetingId, - userId, - authToken, - }); - - if (!user) { - Logger.warn('Couldn\'t find user for feedback'); - } - - res.setHeader('Content-Type', 'application/json'); - res.writeHead(200); - res.end(JSON.stringify({ status: 'ok' })); - - body.userName = user ? user.name : `[unconfirmed] ${reqUserName}`; - - const feedback = { - ...body, - }; - Logger.info('FEEDBACK LOG:', feedback); - })); -}); - -WebApp.connectHandlers.use('/guestWait', (req, res) => { - if (!guestWaitHtml) { - try { - guestWaitHtml = Assets.getText('static/guest-wait/guest-wait.html'); - } catch (e) { - Logger.warn(`Could not process guest wait html file: ${e}`); - } - } - - res.setHeader('Content-Type', 'text/html'); - res.writeHead(200); - res.end(guestWaitHtml); -}); diff --git a/bigbluebutton-html5/imports/startup/server/logger.js b/bigbluebutton-html5/imports/startup/server/logger.js deleted file mode 100755 index 7241b3db07..0000000000 --- a/bigbluebutton-html5/imports/startup/server/logger.js +++ /dev/null @@ -1,45 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { createLogger, format, transports } from 'winston'; -import WinstonPromTransport from './prom-metrics/winstonPromTransport'; - -const LOG_CONFIG = Meteor?.settings?.private?.serverLog || {}; -const { level, includeServerInfo } = LOG_CONFIG; - -const serverInfoFormat = format.printf(({ level, message, timestamp, ...metadata }) => { - const instanceId = parseInt(process.env.INSTANCE_ID, 10) || 1; - const role = process.env.BBB_HTML5_ROLE; - const server = includeServerInfo && !Meteor?.isDevelopment ? `${role}-${instanceId} ` : ""; - - const msg = `${timestamp} ${server}[${level}] : ${message}`; - const meta = Object.keys(metadata).length ? JSON.stringify(metadata) : ''; - return `${msg} ${meta}`; -}); - -const Logger = createLogger({ - level, - format: format.combine( - format.colorize({ level: true }), - format.splat(), - format.simple(), - format.timestamp(), - serverInfoFormat, - ), - transports: [ - // console logging - new transports.Console({ - prettyPrint: false, - humanReadableUnhandledException: true, - colorize: true, - handleExceptions: true, - level, - }), - // export error logs to prometheus - new WinstonPromTransport({ - level: 'error', - }), - ], -}); - -export default Logger; - -export const logger = Logger; diff --git a/bigbluebutton-html5/imports/startup/server/metrics.js b/bigbluebutton-html5/imports/startup/server/metrics.js deleted file mode 100644 index 967fa0d628..0000000000 --- a/bigbluebutton-html5/imports/startup/server/metrics.js +++ /dev/null @@ -1,140 +0,0 @@ -/* eslint-disable no-prototype-builtins */ - -import fs from 'fs'; -import path from 'path'; -import { Meteor } from 'meteor/meteor'; -import Logger from './logger'; - -class Metrics { - constructor() { - this.metrics = {}; - } - - addEvent(meetingId, eventName, messageLength) { - if (!this.metrics.hasOwnProperty(meetingId)) { - this.metrics[meetingId] = { - currentlyInQueue: {}, - wasInQueue: {}, - }; - } - - const { currentlyInQueue } = this.metrics[meetingId]; - - if (!currentlyInQueue.hasOwnProperty(eventName)) { - currentlyInQueue[eventName] = { - count: 1, - payloadSize: messageLength, - }; - } else { - currentlyInQueue[eventName].count += 1; - currentlyInQueue[eventName].payloadSize += messageLength; - } - } - - processEvent(meetingId, eventName, size, processingStartTimestamp) { - const currentProcessingTimestamp = Date.now(); - const processTime = currentProcessingTimestamp - processingStartTimestamp; - - this.addEvent(meetingId, eventName, size); - - if (!this.metrics[meetingId].wasInQueue.hasOwnProperty(eventName)) { - this.metrics[meetingId].wasInQueue[eventName] = { - count: 1, - payloadSize: { - min: size, - max: size, - last: size, - total: size, - avg: size, - }, - processingTime: { - min: processTime, - max: processTime, - last: processTime, - total: processTime, - avg: processTime, - }, - }; - this.metrics[meetingId].currentlyInQueue[eventName].count -= 1; - - if (!this.metrics[meetingId].currentlyInQueue[eventName].count) { - delete this.metrics[meetingId].currentlyInQueue[eventName]; - } - } else { - const { currentlyInQueue, wasInQueue } = this.metrics[meetingId]; - - currentlyInQueue[eventName].count -= 1; - - if (!currentlyInQueue[eventName].count) { - delete currentlyInQueue[eventName]; - } - - const { payloadSize, processingTime } = wasInQueue[eventName]; - - wasInQueue[eventName].count += 1; - - payloadSize.last = size; - payloadSize.total += size; - - if (payloadSize.min > size) payloadSize.min = size; - if (payloadSize.max < size) payloadSize.max = size; - - payloadSize.avg = payloadSize.total / wasInQueue[eventName].count; - - if (processingTime.min > processTime) processingTime.min = processTime; - if (processingTime.max < processTime) processingTime.max = processTime; - - processingTime.last = processTime; - processingTime.total += processTime; - processingTime.avg = processingTime.total / wasInQueue[eventName].count; - } - } - - setAnnotationQueueLength(meetingId, size) { - this.metrics[meetingId].annotationQueueLength = size; - } - - startDumpFile() { - Meteor.setInterval(() => { - try { - const fileDate = new Date(); - const fullYear = fileDate.getFullYear(); - const month = (fileDate.getMonth() + 1).toString().padStart(2, '0'); - const day = fileDate.getDate().toString().padStart(2, '0'); - const hour = fileDate.getHours().toString().padStart(2, '0'); - const minutes = fileDate.getMinutes().toString().padStart(2, '0'); - const seconds = fileDate.getSeconds().toString().padStart(2, '0'); - - const folderName = `${fullYear}${month}${day}_${hour}`; - const fileName = `${folderName}${minutes}${seconds}_metrics.json`; - - const folderPath = path.join(metricsFolderPath, folderName); - const fullFilePath = path.join(folderPath, fileName); - - if (!fs.existsSync(folderPath)) { - Logger.debug(`Creating folder: ${folderPath}`); - fs.mkdirSync(folderPath); - } - - fs.writeFileSync(fullFilePath, JSON.stringify(this.metrics)); - - Logger.info('Metric file successfully written'); - } catch (err) { - Logger.error('Error on writing metrics to disk.', err); - } - }, metricsDumpIntervalMs); - } - - removeMeeting(meetingId) { - if (removeMeetingOnEnd) { - Logger.info(`Removing meeting ${meetingId} from metrics`); - delete this.metrics[meetingId]; - } else { - Logger.info(`Skipping remove of meeting ${meetingId} from metrics`); - } - } -} - -const metricsSingleton = new Metrics(); - -export default metricsSingleton; diff --git a/bigbluebutton-html5/imports/startup/server/minBrowserVersion.js b/bigbluebutton-html5/imports/startup/server/minBrowserVersion.js deleted file mode 100755 index 1bcec1ad81..0000000000 --- a/bigbluebutton-html5/imports/startup/server/minBrowserVersion.js +++ /dev/null @@ -1,19 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { setMinimumBrowserVersions } from 'meteor/modern-browsers'; - -const setMinBrowserVersions = () => { - const { minBrowserVersions } = Meteor.settings.private; - - const versions = {}; - - minBrowserVersions.forEach((elem) => { - let { version } = elem; - if (version === 'Infinity') version = Infinity; - - versions[elem.browser] = version; - }); - - setMinimumBrowserVersions(versions, 'bbb-min'); -}; - -export default setMinBrowserVersions; diff --git a/bigbluebutton-html5/imports/startup/server/prom-metrics/index.js b/bigbluebutton-html5/imports/startup/server/prom-metrics/index.js deleted file mode 100644 index 76d2efad3d..0000000000 --- a/bigbluebutton-html5/imports/startup/server/prom-metrics/index.js +++ /dev/null @@ -1,35 +0,0 @@ -import Agent from './promAgent.js'; - -import { - METRICS_PREFIX, - METRIC_NAMES, - buildMetrics -} from './metrics.js'; - -const { - enabled: METRICS_ENABLED, - path: METRICS_PATH, - collectDefaultMetrics: COLLECT_DEFAULT_METRICS, - } = Meteor.settings.private.prometheus - ? Meteor.settings.private.prometheus - : { enabled: false }; - -const PrometheusAgent = new Agent({ - path: METRICS_PATH, - prefix: METRICS_PREFIX, - collectDefaultMetrics: COLLECT_DEFAULT_METRICS, - role: process.env.BBB_HTML5_ROLE, - instanceId: parseInt(process.env.INSTANCE_ID, 10) || 1, -}); - -if (METRICS_ENABLED) { - PrometheusAgent.injectMetrics(buildMetrics()); - PrometheusAgent.start(); -} - -export { - METRIC_NAMES, - METRICS_PREFIX, - Agent, - PrometheusAgent, -}; diff --git a/bigbluebutton-html5/imports/startup/server/prom-metrics/metrics.js b/bigbluebutton-html5/imports/startup/server/prom-metrics/metrics.js deleted file mode 100644 index 147b6d8678..0000000000 --- a/bigbluebutton-html5/imports/startup/server/prom-metrics/metrics.js +++ /dev/null @@ -1,46 +0,0 @@ -const { - Counter, - Histogram, -} = require('prom-client'); - -const METRICS_PREFIX = 'html5_'; -const METRIC_NAMES = { - METEOR_METHODS: 'meteorMethods', - METEOR_ERRORS_TOTAL: 'meteorErrorsTotal', - METEOR_RTT: 'meteorRtt', -}; - -let METRICS; -const buildMetrics = () => { - if (METRICS == null) { - METRICS = { - [METRIC_NAMES.METEOR_METHODS]: new Counter({ - name: `${METRICS_PREFIX}meteor_methods`, - help: 'Total number of meteor methods processed in html5', - labelNames: ['methodName', 'role', 'instanceId'], - }), - - [METRIC_NAMES.METEOR_ERRORS_TOTAL]: new Counter({ - name: `${METRICS_PREFIX}meteor_errors_total`, - help: 'Total number of errors logs in meteor', - labelNames: ['errorMessage', 'role', 'instanceId'], - }), - - [METRIC_NAMES.METEOR_RTT]: new Histogram({ - name: `${METRICS_PREFIX}meteor_rtt_seconds`, - help: 'Round-trip time of meteor client-server connections in seconds', - buckets: [0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.75, 1, 1.5, 2, 2.5, 5], - labelNames: ['role', 'instanceId'], - }), - }; - } - - return METRICS; -}; - -export { - METRICS_PREFIX, - METRIC_NAMES, - METRICS, - buildMetrics, -}; diff --git a/bigbluebutton-html5/imports/startup/server/prom-metrics/promAgent.js b/bigbluebutton-html5/imports/startup/server/prom-metrics/promAgent.js deleted file mode 100644 index b7c668a808..0000000000 --- a/bigbluebutton-html5/imports/startup/server/prom-metrics/promAgent.js +++ /dev/null @@ -1,96 +0,0 @@ -import { - register, - collectDefaultMetrics, -} from 'prom-client'; - -import Logger from '../logger'; -const LOG_PREFIX = '[prom-scrape-agt]'; - -class PrometheusScrapeAgent { - constructor(options) { - this.metrics = {}; - this.started = false; - - this.path = options.path || '/metrics'; - this.collectDefaultMetrics = options.collectDefaultMetrics || false; - this.metricsPrefix = options.prefix || ''; - this.collectionTimeout = options.collectionTimeout || 10000; - this.roleAndInstanceLabels = - options.role - ? { role: options.role, instanceId: options.instanceId } - : {}; - } - - async collect(response) { - try { - response.writeHead(200, { 'Content-Type': register.contentType }); - const content = await register.metrics(); - response.end(content); - Logger.debug(`${LOG_PREFIX} Collected prometheus metrics:\n${content}`); - } catch (error) { - response.writeHead(500) - response.end(error.message); - Logger.error(`${LOG_PREFIX} Collecting prometheus metrics: ${error.message}`); - } - } - - start() { - if (this.collectDefaultMetrics) collectDefaultMetrics({ - prefix: this.metricsPrefix, - timeout: this.collectionTimeout, - labels: this.roleAndInstanceLabels, - }); - - WebApp.connectHandlers.use(this.path, (req, res) => { - return this.collect(res); - }); - - this.started = true; - }; - - injectMetrics(metricsDictionary) { - this.metrics = { ...this.metrics, ...metricsDictionary } - } - - increment(metricName, labelsObject) { - if (!this.started) return; - - const metric = this.metrics[metricName]; - if (metric) { - labelsObject = { ...labelsObject, ...this.roleAndInstanceLabels }; - metric.inc(labelsObject) - } - } - - decrement(metricName, labelsObject) { - if (!this.started) return; - - const metric = this.metrics[metricName]; - if (metric) { - labelsObject = { ...labelsObject, ...this.roleAndInstanceLabels }; - metric.dec(labelsObject) - } - } - - set(metricName, value, labelsObject) { - if (!this.started) return; - - const metric = this.metrics[metricName]; - if (metric) { - labelsObject = { ...labelsObject, ...this.roleAndInstanceLabels }; - metric.set(labelsObject, value) - } - } - - observe(metricName, value, labelsObject) { - if (!this.started) return; - - const metric = this.metrics[metricName]; - if (metric) { - labelsObject = { ...labelsObject, ...this.roleAndInstanceLabels }; - metric.observe(labelsObject, value) - } - } -} - -export default PrometheusScrapeAgent; diff --git a/bigbluebutton-html5/imports/startup/server/prom-metrics/winstonPromTransport.js b/bigbluebutton-html5/imports/startup/server/prom-metrics/winstonPromTransport.js deleted file mode 100644 index 44669b199a..0000000000 --- a/bigbluebutton-html5/imports/startup/server/prom-metrics/winstonPromTransport.js +++ /dev/null @@ -1,19 +0,0 @@ -const Transport = require('winston-transport'); -import { PrometheusAgent, METRIC_NAMES } from './index.js' - -module.exports = class WinstonPromTransport extends Transport { - constructor(opts) { - super(opts); - - } - - log(info, callback) { - setImmediate(() => { - this.emit('logged', info); - }); - - PrometheusAgent.increment(METRIC_NAMES.METEOR_ERRORS_TOTAL, { errorMessage: info.message }); - - callback(); - } -}; diff --git a/bigbluebutton-html5/imports/startup/server/settings.js b/bigbluebutton-html5/imports/startup/server/settings.js deleted file mode 100644 index bdab48a5bc..0000000000 --- a/bigbluebutton-html5/imports/startup/server/settings.js +++ /dev/null @@ -1,35 +0,0 @@ -/* global __meteor_runtime_config__ */ -import { Meteor } from 'meteor/meteor'; -import fs from 'fs'; -import YAML from 'yaml'; -import { defaultsDeep } from '/imports/utils/array-utils'; - -const DEFAULT_SETTINGS_FILE_PATH = process.env.BBB_HTML5_SETTINGS || 'assets/app/config/settings.yml'; -const LOCAL_SETTINGS_FILE_PATH = process.env.BBB_HTML5_LOCAL_SETTINGS || '/etc/bigbluebutton/bbb-html5.yml'; - -try { - if (fs.existsSync(DEFAULT_SETTINGS_FILE_PATH)) { - let SETTINGS = YAML.parse(fs.readFileSync(DEFAULT_SETTINGS_FILE_PATH, 'utf-8')); - - if (fs.existsSync(LOCAL_SETTINGS_FILE_PATH)) { - console.log('Local configuration found! Merging with default configuration...'); - const LOCAL_CONFIG = YAML.parse(fs.readFileSync(LOCAL_SETTINGS_FILE_PATH, 'utf-8')); - SETTINGS = defaultsDeep(LOCAL_CONFIG, SETTINGS); - } else console.log('Local Configuration not found! Loading default configuration...'); - - Meteor.settings = SETTINGS; - Meteor.settings.public.app.instanceId = ''; // no longer use instanceId in URLs. Likely permanent change - // Meteor.settings.public.app.instanceId = `/${INSTANCE_ID}`; - - Meteor.settings.public.packages = { - 'dynamic-import': { useLocationOrigin: true }, - }; - - __meteor_runtime_config__.PUBLIC_SETTINGS = SETTINGS.public; - } else { - throw new Error('File doesn\'t exists'); - } -} catch (error) { - // eslint-disable-next-line no-console - console.error('Error on load configuration file.', error); -} diff --git a/bigbluebutton-html5/imports/ui/Types/meeting.ts b/bigbluebutton-html5/imports/ui/Types/meeting.ts index c46301c75d..977fba8da6 100644 --- a/bigbluebutton-html5/imports/ui/Types/meeting.ts +++ b/bigbluebutton-html5/imports/ui/Types/meeting.ts @@ -7,6 +7,7 @@ export interface LockSettings { hasActiveLockSetting: boolean; hideUserList: boolean; hideViewersCursor: boolean; + hideViewersAnnotation: false, meetingId: boolean; webcamsOnlyForModerator: boolean; lockOnJoin: boolean; @@ -20,8 +21,7 @@ export interface groups { export interface WelcomeSettings { welcomeMsg: string; - modOnlyMessage: string; - welcomeMsgTemplate: string; + welcomeMsgForModerators: string; meetingId: string; } @@ -104,6 +104,7 @@ export interface ComponentsFlags { hasScreenshare: boolean; hasTimer: boolean; showRemainingTime: boolean; + hasCameraAsContent: boolean; } export interface Metadata { diff --git a/bigbluebutton-html5/imports/ui/Types/meetingClientSettings.ts b/bigbluebutton-html5/imports/ui/Types/meetingClientSettings.ts index 2a0a27cdc8..50790c04cf 100644 --- a/bigbluebutton-html5/imports/ui/Types/meetingClientSettings.ts +++ b/bigbluebutton-html5/imports/ui/Types/meetingClientSettings.ts @@ -13,7 +13,6 @@ export interface Public { timer: Timer chat: Chat userReaction: UserReaction - userStatus: UserStatus notes: Notes layout: Layout pads: Pads @@ -30,7 +29,6 @@ export interface Locales { name: string } export interface App { - instanceId: string mobileFontSize: string desktopFontSize: string audioChatNotification: boolean @@ -86,12 +84,11 @@ export interface App { customHeartbeat: boolean showAllAvailableLocales: boolean showAudioFilters: boolean - raiseHandActionButton: RaiseHandActionButton reactionsButton: ReactionsButton emojiRain: EmojiRain enableNetworkStats: boolean enableCopyNetworkStatsButton: boolean - userSettingsStorage: string + userSettingsStorage: 'local' | 'session' defaultSettings: DefaultSettings shortcuts: Shortcuts branding: Branding @@ -118,6 +115,7 @@ export interface WakeLock { } export interface AudioCaptions { + alwaysVisible: boolean enabled: boolean mobile: boolean provider: string @@ -144,6 +142,7 @@ export interface Breakouts { captureSharedNotesByDefault: boolean sendInvitationToAssignedModeratorsByDefault: boolean breakoutRoomLimit: number + allowPresentationManagementInBreakouts: boolean } export interface RaiseHandActionButton { @@ -162,10 +161,16 @@ export interface EmojiRain { emojiSize: number } +export interface Transcription { + partialUtterances: boolean + minUtteranceLength: number +} + export interface DefaultSettings { application: Application audio: Audio dataSaving: DataSaving + transcription: Transcription } export interface Application { @@ -184,6 +189,7 @@ export interface Application { wakeLock: boolean paginationEnabled: boolean whiteboardToolbarAutoHide: boolean + pushToTalkEnabled: boolean autoCloseReactionsBar: boolean darkTheme: boolean fallbackLocale: string @@ -457,6 +463,10 @@ export interface Captions { lines: number time: number locales: Locales[] + defaultPad: string + showButton: boolean + lineLimit: number + captionLimit: number } export interface Font { @@ -510,6 +520,7 @@ export interface Chat { system_messages_keys: SystemMessagesKeys typingIndicator: TypingIndicator moderatorChatEmphasized: boolean + privateMessageReadFeedback: MessageReadFeedback autoConvertEmoji: boolean emojiPicker: EmojiPicker disableEmojis: string[] @@ -528,6 +539,10 @@ export interface TypingIndicator { showNames: boolean } +export interface MessageReadFeedback { + enabled: boolean +} + export interface EmojiPicker { enable: boolean } @@ -543,10 +558,6 @@ export interface Reaction { native: string } -export interface UserStatus { - enabled: boolean -} - export interface Notes { enabled: boolean id: string @@ -600,7 +611,7 @@ export interface Media { traceSip: boolean sdpSemantics: string localEchoTest: LocalEchoTest - showVolumeMeter: boolean + muteAudioOutputWhenAway: boolean } export interface Audio2 { @@ -634,7 +645,6 @@ export interface Stats { timeout: number log: boolean notification: Notification - jitter: number[] loss: number[] rtt: number[] level: string[] @@ -688,6 +698,8 @@ export interface Whiteboard { maxStickyNoteLength: number maxNumberOfAnnotations: number annotations: Annotations + allowInfiniteWhiteboard: boolean + allowInfiniteWhiteboardInBreakouts: boolean styles: Styles toolbar: Toolbar } @@ -739,16 +751,10 @@ export interface Tool { } export interface ClientLog { - server: Server console: Console external: External } -export interface Server { - enabled: boolean - level: string -} - export interface Console { enabled: boolean level: string @@ -777,7 +783,6 @@ export interface VirtualBackgrounds { export interface Private { analytics: Analytics app: App2 - serverLog: ServerLog minBrowserVersions: MinBrowserVersion[] prometheus: Prometheus } @@ -805,18 +810,6 @@ export interface Channels { toThirdParty: string } -export interface ServerLog { - level: string - streamerLog: boolean - includeServerInfo: boolean - healthChecker: HealthChecker -} - -export interface HealthChecker { - enable: boolean - intervalMs: number -} - export interface MinBrowserVersion { browser: string version: number | number[] | string diff --git a/bigbluebutton-html5/imports/ui/Types/message.ts b/bigbluebutton-html5/imports/ui/Types/message.ts index 112b57c5af..7e2b582a40 100644 --- a/bigbluebutton-html5/imports/ui/Types/message.ts +++ b/bigbluebutton-html5/imports/ui/Types/message.ts @@ -13,5 +13,6 @@ export interface Message { senderName: string; senderRole: string; messageMetadata: string; + recipientHasSeen: string; user: User; } diff --git a/bigbluebutton-html5/imports/ui/Types/user.ts b/bigbluebutton-html5/imports/ui/Types/user.ts index 21dd93870a..bda5277022 100644 --- a/bigbluebutton-html5/imports/ui/Types/user.ts +++ b/bigbluebutton-html5/imports/ui/Types/user.ts @@ -34,37 +34,28 @@ export interface Voice { endTime: number; floor: boolean; lastFloorTime: string - lastSpeakChangedAt: number; meetingId: string; spoke: boolean; startTime: number; } -export interface CustomParameter { +export interface UserMetadata { parameter: string; value: string; } -export interface Reaction { - reactionEmoji: string; -} - export interface BreakoutRooms { - currentRoomJoined: boolean; + hasJoined: boolean; assignedAt: string; breakoutRoomId: string; - currentRoomIsOnline: boolean | null; - currentRoomPriority: number; - currentRoomRegisteredAt: string | null; + isUserCurrentlyInRoom: boolean | null; + isLastAssignedRoom: boolean | null; durationInSeconds: number; endedAt: string | null; freeJoin: boolean; inviteDismissedAt: string | null; isDefaultName: boolean; joinURL: string; - lastRoomIsOnline: boolean; - lastRoomJoinedAt: string; - lastRoomJoinedId: string; name: string; sendInvitationToModerators: boolean; sequence: number; @@ -72,9 +63,6 @@ export interface BreakoutRooms { showInvitation: boolean; startedAt: string; } -export interface UserClientSettings { - userClientSettingsJson: string; -} export interface User { authToken: string; @@ -82,13 +70,10 @@ export interface User { extId: string; name: string; nameSortable: string; - banned: boolean; isModerator: boolean; clientType: string; disconnected: boolean; - isOnline: boolean; - isRunningEchoTest: boolean; - echoTestRunningAt: number; + currentlyInMeeting: boolean; ejectReason: string; ejectReasonCode: string; ejected: boolean; @@ -96,13 +81,15 @@ export interface User { role: string; color: string; avatar: string; - emoji: string; + webcamBackground: string; + reactionEmoji: string; presenter?: boolean; pinned?: boolean; guest?: boolean; guestStatus: string; joinErrorCode: string; joinErrorMessage: string; + inactivityWarningDisplay: boolean; joined: boolean; loggedOut: boolean; mobile?: boolean; @@ -111,18 +98,15 @@ export interface User { voice?: Partial; locked: boolean; registeredAt: string; - registeredOn: number; hasDrawPermissionOnCurrentPage: boolean; lastBreakoutRoom?: LastBreakoutRoom; cameras: Array; presPagesWritable: Array; speechLocale: string; + captionLocale: string; authed: boolean; size: number; away: boolean; raiseHand: boolean; - reaction: Reaction; breakoutRooms: BreakoutRooms; - customParameters: Array; - userClientSettings: UserClientSettings; } diff --git a/bigbluebutton-html5/imports/ui/Types/userVoice.ts b/bigbluebutton-html5/imports/ui/Types/userVoice.ts index 485d9d0cda..e3be93c64c 100644 --- a/bigbluebutton-html5/imports/ui/Types/userVoice.ts +++ b/bigbluebutton-html5/imports/ui/Types/userVoice.ts @@ -1,7 +1,6 @@ import { User } from './user'; export interface UserVoice { - showTalkingIndicator: boolean; callerName: string; callerNum: number; callingWith: string; @@ -11,7 +10,6 @@ export interface UserVoice { hideTalkingIndicatorAt: number; joined: boolean; lastFloorTime: number; - lastSpeakChangedAt: number; listenOnly: boolean; meetingId: string; muted: boolean; diff --git a/bigbluebutton-html5/imports/ui/components/about/component.jsx b/bigbluebutton-html5/imports/ui/components/about/component.jsx index a240891d92..dd908d2adc 100644 --- a/bigbluebutton-html5/imports/ui/components/about/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/about/component.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { defineMessages, injectIntl } from 'react-intl'; +import { defineMessages, injectIntl, useIntl } from 'react-intl'; import ModalSimple from '/imports/ui/components/common/modal/simple/component'; const intlMessages = defineMessages({ @@ -39,7 +39,10 @@ const intlMessages = defineMessages({ }); const AboutComponent = (props) => { - const { intl, settings, isOpen, onRequestClose, priority, } = props; + const { + settings, isOpen, onRequestClose, priority, + } = props; + const intl = useIntl(); const { html5ClientBuild, copyright, diff --git a/bigbluebutton-html5/imports/ui/components/about/container.jsx b/bigbluebutton-html5/imports/ui/components/about/container.jsx index 4b9c12d806..17135953e9 100644 --- a/bigbluebutton-html5/imports/ui/components/about/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/about/container.jsx @@ -1,22 +1,14 @@ import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; import AboutComponent from './component'; const AboutContainer = (props) => { - const { children } = props; + const { children, ...rest } = props; return ( - + {children} ); }; -const getClientBuildInfo = () => ( - { - settings: window.meetingClientSettings.public.app, - - } -); - -export default withTracker(() => getClientBuildInfo())(AboutContainer); +export default AboutContainer; diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx index 0e5745d0c0..6de733fdac 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx @@ -10,10 +10,10 @@ import Styled from './styles'; import { colorPrimary } from '/imports/ui/stylesheets/styled-components/palette'; import { PANELS, ACTIONS, LAYOUT_TYPE } from '../../layout/enums'; import { uniqueId } from '/imports/utils/string-utils'; -import { isPresentationEnabled, isLayoutsEnabled } from '/imports/ui/services/features'; import VideoPreviewContainer from '/imports/ui/components/video-preview/container'; import { screenshareHasEnded } from '/imports/ui/components/screenshare/service'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; +import Session from '/imports/ui/services/storage/in-memory'; const propTypes = { amIPresenter: PropTypes.bool, @@ -39,11 +39,13 @@ const propTypes = { key: PropTypes.string, }), ).isRequired, + isPresentationManagementDisabled: PropTypes.bool, }; const defaultProps = { shortcuts: '', settingsLayout: LAYOUT_TYPE.SMART_LAYOUT, + isPresentationManagementDisabled: false, amIPresenter: false, amIModerator: false, }; @@ -115,7 +117,7 @@ const intlMessages = defineMessages({ }, }); -const handlePresentationClick = () => Session.set('showUploadPresentationView', true); +const handlePresentationClick = () => Session.setItem('showUploadPresentationView', true); class ActionsDropdown extends PureComponent { constructor(props) { @@ -182,6 +184,9 @@ class ActionsDropdown extends PureComponent { isTimerFeatureEnabled, presentations, isDirectLeaveButtonEnabled, + isLayoutsEnabled, + isPresentationEnabled, + isPresentationManagementDisabled, } = this.props; const { pollBtnLabel, presentationLabel, takePresenter } = intlMessages; @@ -190,7 +195,7 @@ class ActionsDropdown extends PureComponent { const actions = []; - if (amIPresenter && isPresentationEnabled()) { + if (amIPresenter && !isPresentationManagementDisabled && isPresentationEnabled) { if (presentations && presentations.length > 1) { actions.push({ key: 'separator-01', @@ -214,7 +219,7 @@ class ActionsDropdown extends PureComponent { key: this.pollId, onClick: () => { if (Session.equals('pollInitiated', true)) { - Session.set('resetPollPanel', true); + Session.setItem('resetPollPanel', true); } layoutContextDispatch({ type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, @@ -224,7 +229,7 @@ class ActionsDropdown extends PureComponent { type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, value: PANELS.POLL, }); - Session.set('forcePollOpen', true); + Session.setItem('forcePollOpen', true); }, }); } @@ -262,12 +267,13 @@ class ActionsDropdown extends PureComponent { }); } + const Settings = getSettingsSingletonInstance(); const { selectedLayout } = Settings.application; const shouldShowManageLayoutButton = selectedLayout !== LAYOUT_TYPE.CAMERAS_ONLY && selectedLayout !== LAYOUT_TYPE.PRESENTATION_ONLY && selectedLayout !== LAYOUT_TYPE.PARTICIPANTS_AND_CHAT_ONLY; - if (shouldShowManageLayoutButton && isLayoutsEnabled()) { + if (shouldShowManageLayoutButton && isLayoutsEnabled && (amIModerator || amIPresenter)) { actions.push({ icon: 'manage_layout', label: intl.formatMessage(intlMessages.layoutModal), diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/container.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/container.jsx index d014ed433e..24d96c54bf 100644 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/container.jsx @@ -1,21 +1,26 @@ import React, { useContext } from 'react'; +import { useMutation } from '@apollo/client'; import ActionsDropdown from './component'; import { layoutSelectInput, layoutDispatch, layoutSelect } from '../../layout/context'; import { SMALL_VIEWPORT_BREAKPOINT, ACTIONS, PANELS } from '../../layout/enums'; -import { isCameraAsContentEnabled, isTimerFeatureEnabled } from '/imports/ui/services/features'; +import { + useIsCameraAsContentEnabled, + useIsLayoutsEnabled, + useIsPresentationEnabled, + useIsTimerFeatureEnabled, +} from '/imports/ui/services/features'; import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; -import { useSubscription, useMutation } from '@apollo/client'; import { useShortcut } from '/imports/ui/core/hooks/useShortcut'; import { PROCESSED_PRESENTATIONS_SUBSCRIPTION, } from '/imports/ui/components/whiteboard/queries'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; import { SET_PRESENTER } from '/imports/ui/core/graphql/mutations/userMutations'; import { TIMER_ACTIVATE, TIMER_DEACTIVATE } from '../../timer/mutations'; import Auth from '/imports/ui/services/auth'; import { PRESENTATION_SET_CURRENT } from '../../presentation/mutations'; - -const TIMER_CONFIG = window.meetingClientSettings.public.timer; -const MILLI_IN_MINUTE = 60000; +import { useStorageKey } from '/imports/ui/services/storage/hooks'; +import { useMeetingIsBreakout } from '/imports/ui/components/app/service'; const ActionsDropdownContainer = (props) => { const sidebarContent = layoutSelectInput((i) => i.sidebarContent); @@ -25,6 +30,8 @@ const ActionsDropdownContainer = (props) => { const layoutContextDispatch = layoutDispatch(); const isRTL = layoutSelect((i) => i.isRTL); const { pluginsExtensibleAreasAggregatedState } = useContext(PluginsContext); + const meetingIsBreakout = useMeetingIsBreakout(); + let actionButtonDropdownItems = []; if (pluginsExtensibleAreasAggregatedState.actionButtonDropdownItems) { actionButtonDropdownItems = [...pluginsExtensibleAreasAggregatedState.actionButtonDropdownItems]; @@ -32,9 +39,18 @@ const ActionsDropdownContainer = (props) => { const openActions = useShortcut('openActions'); - const { data: presentationData } = useSubscription(PROCESSED_PRESENTATIONS_SUBSCRIPTION); + const { data: presentationData } = useDeduplicatedSubscription( + PROCESSED_PRESENTATIONS_SUBSCRIPTION, + ); const presentations = presentationData?.pres_presentation || []; + const { + allowPresentationManagementInBreakouts, + } = window.meetingClientSettings.public.app.breakouts; + + const isPresentationManagementDisabled = meetingIsBreakout + && !allowPresentationManagementInBreakouts; + const [setPresenter] = useMutation(SET_PRESENTER); const [timerActivate] = useMutation(TIMER_ACTIVATE); const [timerDeactivate] = useMutation(TIMER_DEACTIVATE); @@ -49,6 +65,8 @@ const ActionsDropdownContainer = (props) => { }; const activateTimer = () => { + const TIMER_CONFIG = window.meetingClientSettings.public.timer; + const MILLI_IN_MINUTE = 60000; const stopwatch = true; const running = false; const time = TIMER_CONFIG.time * MILLI_IN_MINUTE; @@ -67,6 +85,12 @@ const ActionsDropdownContainer = (props) => { }, 500); }; + const isDropdownOpen = useStorageKey('dropdownOpen'); + const isLayoutsEnabled = useIsLayoutsEnabled(); + const isPresentationEnabled = useIsPresentationEnabled(); + const isTimerFeatureEnabled = useIsTimerFeatureEnabled(); + const isCameraAsContentEnabled = useIsCameraAsContentEnabled(); + return ( { isRTL, actionButtonDropdownItems, presentations, - isTimerFeatureEnabled: isTimerFeatureEnabled(), - isDropdownOpen: Session.get('dropdownOpen'), + isTimerFeatureEnabled, + isDropdownOpen, setPresentation, - isCameraAsContentEnabled: isCameraAsContentEnabled(), + isCameraAsContentEnabled, handleTakePresenter, activateTimer, deactivateTimer: timerDeactivate, shortcuts: openActions, + isLayoutsEnabled, + isPresentationEnabled, + isPresentationManagementDisabled, ...props, }} /> diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx index 19f30b4856..3744ebcc92 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx @@ -4,21 +4,18 @@ import Styled from './styles'; import ActionsDropdown from './actions-dropdown/container'; import AudioCaptionsButtonContainer from '/imports/ui/components/audio/audio-graphql/audio-captions/button/component'; import ScreenshareButtonContainer from '/imports/ui/components/actions-bar/screenshare/container'; -import ReactionsButtonContainer from './reactions-button/container'; import AudioControlsContainer from '../audio/audio-graphql/audio-controls/component'; -import JoinVideoOptionsContainer from '../video-provider/video-provider-graphql/video-button/container'; +import JoinVideoOptionsContainer from '../video-provider/video-button/container'; import PresentationOptionsContainer from './presentation-options/component'; -import RaiseHandDropdownContainer from './raise-hand/container'; -import { isPresentationEnabled } from '/imports/ui/services/features'; import Button from '/imports/ui/components/common/button/component'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import { LAYOUT_TYPE } from '../layout/enums'; +import ReactionsButtonContainer from '/imports/ui/components/actions-bar/reactions-button/container'; class ActionsBar extends PureComponent { constructor(props) { super(props); - this.setRenderRaiseHand = this.renderRaiseHand.bind(this); this.actionsBarRef = React.createRef(); this.renderPluginsActionBarItems = this.renderPluginsActionBarItems.bind(this); } @@ -63,22 +60,11 @@ class ActionsBar extends PureComponent { ); } - renderRaiseHand() { - const { - isReactionsButtonEnabled, isRaiseHandButtonEnabled, currentUser, intl, - } = this.props; - + renderReactionsButton() { return ( <> - {isReactionsButtonEnabled - ? ( - <> - - - - ) - : isRaiseHandButtonEnabled ? - : null} + + ); } @@ -101,7 +87,6 @@ class ActionsBar extends PureComponent { isTimerEnabled, isMeteorConnected, isPollingEnabled, - isRaiseHandButtonCentered, isThereCurrentPresentation, allowExternalVideo, layoutContextDispatch, @@ -110,16 +95,17 @@ class ActionsBar extends PureComponent { showPushLayout, setPushLayout, setPresentationFitToWidth, - + isPresentationEnabled, } = this.props; + const Settings = getSettingsSingletonInstance(); const { selectedLayout } = Settings.application; const shouldShowPresentationButton = selectedLayout !== LAYOUT_TYPE.CAMERAS_ONLY && selectedLayout !== LAYOUT_TYPE.PARTICIPANTS_AND_CHAT_ONLY; const shouldShowVideoButton = selectedLayout !== LAYOUT_TYPE.PRESENTATION_ONLY && selectedLayout !== LAYOUT_TYPE.PARTICIPANTS_AND_CHAT_ONLY; - const shouldShowOptionsButton = (isPresentationEnabled() && isThereCurrentPresentation) + const shouldShowOptionsButton = (isPresentationEnabled && isThereCurrentPresentation) || isSharingVideo || hasScreenshare || isSharedNotesPinned; return ( @@ -169,7 +155,7 @@ class ActionsBar extends PureComponent { }} /> )} - {isRaiseHandButtonCentered && this.renderRaiseHand()} + {this.renderReactionsButton()} {this.renderPluginsActionBarItems(ActionsBarPosition.RIGHT)} @@ -188,7 +174,6 @@ class ActionsBar extends PureComponent { /> ) : null} - {!isRaiseHandButtonCentered && this.renderRaiseHand()} ); diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx index cf3b8cee66..70859f85af 100644 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx @@ -1,14 +1,22 @@ import React, { useContext } from 'react'; -import { Meteor } from 'meteor/meteor'; -import { withTracker } from 'meteor/react-meteor-data'; -import { injectIntl } from 'react-intl'; -import { useSubscription, useMutation } from '@apollo/client'; +import { useIntl } from 'react-intl'; +import { useMutation, useReactiveVar } from '@apollo/client'; import getFromUserSettings from '/imports/ui/services/users-settings'; import Auth from '/imports/ui/services/auth'; import ActionsBar from './component'; -import { layoutSelectOutput, layoutDispatch } from '../layout/context'; -import { isExternalVideoEnabled, isPollingEnabled, isPresentationEnabled, isTimerFeatureEnabled } from '/imports/ui/services/features'; -import { isScreenBroadcasting, isCameraAsContentBroadcasting } from '/imports/ui/components/screenshare/service'; +import { + layoutSelectOutput, + layoutSelectInput, + layoutDispatch, + layoutSelect, +} from '../layout/context'; +import { + useIsExternalVideoEnabled, + useIsPollingEnabled, + useIsPresentationEnabled, + useIsTimerFeatureEnabled, +} from '/imports/ui/services/features'; + import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; import { CURRENT_PRESENTATION_PAGE_SUBSCRIPTION, @@ -18,17 +26,30 @@ import useMeeting from '/imports/ui/core/hooks/useMeeting'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; import { EXTERNAL_VIDEO_STOP } from '../external-video-player/mutations'; import { PINNED_PAD_SUBSCRIPTION } from '../notes/queries'; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; +import connectionStatus from '../../core/graphql/singletons/connectionStatus'; -const NOTES_CONFIG = window.meetingClientSettings.public.notes; +const isReactionsButtonEnabled = () => { + const USER_REACTIONS_ENABLED = window.meetingClientSettings.public.userReaction.enabled; + const REACTIONS_BUTTON_ENABLED = window.meetingClientSettings.public.app.reactionsButton.enabled; + + return USER_REACTIONS_ENABLED && REACTIONS_BUTTON_ENABLED; +}; const ActionsBarContainer = (props) => { + const NOTES_CONFIG = window.meetingClientSettings.public.notes; const actionsBarStyle = layoutSelectOutput((i) => i.actionBar); const layoutContextDispatch = layoutDispatch(); - const { data: presentationPageData } = useSubscription(CURRENT_PRESENTATION_PAGE_SUBSCRIPTION); + const { data: presentationPageData } = useDeduplicatedSubscription( + CURRENT_PRESENTATION_PAGE_SUBSCRIPTION, + ); const presentationPage = presentationPageData?.pres_page_curr[0] || {}; const isThereCurrentPresentation = !!presentationPage?.presentationId; + const genericMainContent = layoutSelectInput((i) => i.genericMainContent); + const isThereGenericMainContent = !!genericMainContent.genericContentId; + const { data: currentMeeting } = useMeeting((m) => ({ externalVideo: m.externalVideo, componentsFlags: m.componentsFlags, @@ -48,26 +69,28 @@ const ActionsBarContainer = (props) => { const { data: currentUserData } = useCurrentUser((user) => ({ presenter: user.presenter, - emoji: user.emoji, isModerator: user.isModerator, })); - const [stopExternalVideoShare] = useMutation(EXTERNAL_VIDEO_STOP); const currentUser = { userId: Auth.userID, - emoji: currentUserData?.emoji, }; const amIPresenter = currentUserData?.presenter; const amIModerator = currentUserData?.isModerator; - const { data: pinnedPadData } = useSubscription(PINNED_PAD_SUBSCRIPTION); + const { data: pinnedPadData } = useDeduplicatedSubscription(PINNED_PAD_SUBSCRIPTION); const isSharedNotesPinnedFromGraphql = !!pinnedPadData && pinnedPadData.sharedNotes[0]?.sharedNotesExtId === NOTES_CONFIG.id; const isSharedNotesPinned = isSharedNotesPinnedFromGraphql; - + const allowExternalVideo = useIsExternalVideoEnabled(); + const connected = useReactiveVar(connectionStatus.getConnectedStatusVar()); + const intl = useIntl(); + const isPresentationEnabled = useIsPresentationEnabled(); + const isTimerFeatureEnabled = useIsTimerFeatureEnabled(); + const isPollingEnabled = useIsPollingEnabled() && isPresentationEnabled; if (actionsBarStyle.display === false) return null; if (!currentMeeting) return null; @@ -75,6 +98,17 @@ const ActionsBarContainer = (props) => { { stopExternalVideoShare, isSharedNotesPinned, isTimerActive: currentMeeting.componentsFlags.hasTimer, - isTimerEnabled: isTimerFeatureEnabled(), + isTimerEnabled: isTimerFeatureEnabled, + hasGenericContent: isThereGenericMainContent, } } /> ); }; -const RAISE_HAND_BUTTON_ENABLED = window.meetingClientSettings - .public.app.raiseHandActionButton.enabled; -const RAISE_HAND_BUTTON_CENTERED = window.meetingClientSettings - .public.app.raiseHandActionButton.centered; - -const isReactionsButtonEnabled = () => { - const USER_REACTIONS_ENABLED = window.meetingClientSettings.public.userReaction.enabled; - const REACTIONS_BUTTON_ENABLED = window.meetingClientSettings.public.app.reactionsButton.enabled; - - return USER_REACTIONS_ENABLED && REACTIONS_BUTTON_ENABLED; -}; - -export default withTracker(() => ({ - enableVideo: getFromUserSettings('bbb_enable_video', window.meetingClientSettings.public.kurento.enableVideo), - setPresentationIsOpen: MediaService.setPresentationIsOpen, - hasScreenshare: isScreenBroadcasting(), - hasCameraAsContent: isCameraAsContentBroadcasting(), - isMeteorConnected: Meteor.status().connected, - isPollingEnabled: isPollingEnabled() && isPresentationEnabled(), - isRaiseHandButtonEnabled: RAISE_HAND_BUTTON_ENABLED, - isRaiseHandButtonCentered: RAISE_HAND_BUTTON_CENTERED, - isReactionsButtonEnabled: isReactionsButtonEnabled(), - allowExternalVideo: isExternalVideoEnabled(), -}))(injectIntl(ActionsBarContainer)); +export default ActionsBarContainer; diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/presentation-options/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/presentation-options/component.jsx index fabbe6b787..580ef8e038 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/presentation-options/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/presentation-options/component.jsx @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; import Button from '/imports/ui/components/common/button/component'; - +import Session from '/imports/ui/services/storage/in-memory'; const propTypes = { intl: PropTypes.shape({ @@ -55,6 +55,10 @@ const PresentationOptionsContainer = ({ const isThereCurrentPresentation = hasExternalVideo || hasScreenshare || hasPresentation || hasPinnedSharedNotes || hasGenericContent || hasCameraAsContent; + const onlyPresentation = hasPresentation + && !hasExternalVideo && !hasScreenshare + && !hasPinnedSharedNotes && !hasGenericContent + && !hasCameraAsContent; return (
+ { presentations.length > 0 && !isUpdate ? ( + + + { currentPresentation ? ( + + ) : null } + { + presentations.map((presentation) => ( + + )) + } + + + ) : null } MIN_BREAKOUT_ROOMS ? BREAKOUT_LIM : MIN_BREAKOUT_ROOMS; const MIN_BREAKOUT_TIME = 5; const DEFAULT_BREAKOUT_TIME = 15; +const CURRENT_SLIDE_PREFIX = 'current-'; interface CreateBreakoutRoomContainerProps { isOpen: boolean @@ -43,6 +46,8 @@ interface CreateBreakoutRoomProps extends CreateBreakoutRoomContainerProps { isBreakoutRecordable: boolean, users: Array, runningRooms: getBreakoutsResponse['breakoutRoom'], + presentations: Array, + currentPresentation: string, } const intlMessages = defineMessages({ @@ -220,6 +225,8 @@ const CreateBreakoutRoom: React.FC = ({ isBreakoutRecordable, users, runningRooms, + presentations, + currentPresentation, }) => { const { isMobile } = deviceInfo; const intl = useIntl(); @@ -234,6 +241,9 @@ const CreateBreakoutRoom: React.FC = ({ const [inviteMods, setInviteMods] = React.useState(false); const [numberOfRooms, setNumberOfRooms] = React.useState(MIN_BREAKOUT_ROOMS); const [durationTime, setDurationTime] = React.useState(DEFAULT_BREAKOUT_TIME); + const isImportPresentationWithAnnotationsEnabled = useIsImportPresentationWithAnnotationsFromBreakoutRoomsEnabled(); + const isImportSharedNotesEnabled = useIsImportSharedNotesFromBreakoutRoomsEnabled(); + const [roomPresentations, setRoomPresentations] = React.useState([]); const [createBreakoutRoom] = useMutation(BREAKOUT_ROOM_CREATE); const [moveUser] = useMutation(BREAKOUT_ROOM_MOVE_USER); @@ -254,6 +264,11 @@ const CreateBreakoutRoom: React.FC = ({ call(checked); }; + const getRoomPresentation = (position: number) => { + if (roomPresentations[position]) return roomPresentations[position]; + return `${CURRENT_SLIDE_PREFIX}${currentPresentation}`; + }; + const createRoom = () => { const rooms = roomsRef.current; const roomsArray: RoomToWithSettings[] = []; @@ -273,6 +288,8 @@ const CreateBreakoutRoom: React.FC = ({ users: r.users.map((u) => u.userId), freeJoin, shortName: r.name, + allPages: !getRoomPresentation(r.id).startsWith(CURRENT_SLIDE_PREFIX), + presId: getRoomPresentation(r.id).replace(CURRENT_SLIDE_PREFIX, ''), }); } else { const defaultName = intl.formatMessage(intlMessages.breakoutRoom, { @@ -288,6 +305,8 @@ const CreateBreakoutRoom: React.FC = ({ freeJoin, shortName: defaultName, users: [], + allPages: !getRoomPresentation(roomNumber).startsWith(CURRENT_SLIDE_PREFIX), + presId: getRoomPresentation(roomNumber).replace(CURRENT_SLIDE_PREFIX, ''), }); } } @@ -353,7 +372,7 @@ const CreateBreakoutRoom: React.FC = ({ label: intl.formatMessage(intlMessages.record), }, { - allowed: isImportPresentationWithAnnotationsFromBreakoutRoomsEnabled(), + allowed: isImportPresentationWithAnnotationsEnabled, htmlFor: 'captureSlidesBreakoutCheckbox', key: 'capture-slides-breakouts', id: 'captureSlidesBreakoutCheckbox', @@ -361,7 +380,7 @@ const CreateBreakoutRoom: React.FC = ({ label: intl.formatMessage(intlMessages.captureSlidesLabel), }, { - allowed: isImportSharedNotesFromBreakoutRoomsEnabled(), + allowed: isImportSharedNotesEnabled, htmlFor: 'captureNotesBreakoutCheckbox', key: 'capture-notes-breakouts', id: 'captureNotesBreakoutCheckbox', @@ -377,9 +396,14 @@ const CreateBreakoutRoom: React.FC = ({ label: intl.formatMessage(intlMessages.sendInvitationToMods), }, ]; - }, [isBreakoutRecordable]); + }, [isBreakoutRecordable, isImportPresentationWithAnnotationsEnabled, isImportSharedNotesEnabled]); const form = useMemo(() => { + if (isUpdate) return null; + + const BREAKOUT_LIM = window.meetingClientSettings.public.app.breakouts.breakoutRoomLimit; + const MAX_BREAKOUT_ROOMS = BREAKOUT_LIM > MIN_BREAKOUT_ROOMS ? BREAKOUT_LIM : MIN_BREAKOUT_ROOMS; + return ( @@ -463,7 +487,10 @@ const CreateBreakoutRoom: React.FC = ({ ); - }, [durationTime, durationIsValid, numberOfRooms, numberOfRoomsIsValid]); + }, [ + durationTime, durationIsValid, numberOfRooms, numberOfRoomsIsValid, + isImportPresentationWithAnnotationsEnabled, isImportSharedNotesEnabled, + ]); return ( = ({ setRoomsRef={setRoomsRef} setMoveRegisterRef={setMoveRegisterRef} setFormIsValid={setLeastOneUserIsValid} + roomPresentations={roomPresentations} + setRoomPresentations={setRoomPresentations} + presentations={presentations} + currentPresentation={currentPresentation} + currentSlidePrefix={CURRENT_SLIDE_PREFIX} + getRoomPresentation={getRoomPresentation} + isUpdate={isUpdate} /> @@ -512,7 +546,7 @@ const CreateBreakoutRoomContainer: React.FC = isOpen, setIsOpen, priority, - isUpdate, + isUpdate = false, }) => { const [fetchedBreakouts, setFetchedBreakouts] = React.useState(false); // isBreakoutRecordable - get from meeting breakout policies breakoutPolicies/record @@ -541,16 +575,20 @@ const CreateBreakoutRoomContainer: React.FC = fetchPolicy: 'network-only', }); + const { data: presentationData } = useDeduplicatedSubscription(PRESENTATIONS_SUBSCRIPTION); + const presentations = presentationData?.pres_presentation || []; + const currentPresentation = presentations.find((p: Presentation) => p.current)?.presentationId || ''; + if (usersLoading || breakoutsLoading || !currentMeeting) { return null; } - if (true && !fetchedBreakouts) { + if (!fetchedBreakouts) { loadBreakouts(); setFetchedBreakouts(true); } - if (true && breakoutsLoading) return null; + if (breakoutsLoading) return null; if (usersError || breakoutsError) { logger.info('Error loading users', usersError); @@ -570,16 +608,10 @@ const CreateBreakoutRoomContainer: React.FC = isBreakoutRecordable={currentMeeting?.breakoutPolicies?.record ?? true} users={usersData?.user ?? []} runningRooms={breakoutsData?.breakoutRoom ?? []} + presentations={presentations} + currentPresentation={currentPresentation} /> ); }; -CreateBreakoutRoomContainer.defaultProps = { - isUpdate: false, -}; - -CreateBreakoutRoom.defaultProps = { - isUpdate: false, -}; - export default CreateBreakoutRoomContainer; diff --git a/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/queries.ts b/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/queries.ts index 487dc6db31..d6efb10310 100644 --- a/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/queries.ts +++ b/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/queries.ts @@ -29,7 +29,6 @@ export const getUser = gql` {role: asc}, {raiseHandTime: asc_nulls_last}, {awayTime: asc_nulls_last}, - {emojiTime: asc_nulls_last}, {isDialIn: desc}, {hasDrawPermissionOnCurrentPage: desc}, {nameSortable: asc}, diff --git a/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/room-managment-state/component.tsx b/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/room-managment-state/component.tsx index e9f66159a3..84f95f3727 100644 --- a/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/room-managment-state/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/room-managment-state/component.tsx @@ -6,6 +6,8 @@ import { ChildComponentProps, Room, moveUserRegistery, + Presentation, + RoomPresentations, } from './types'; import { breakoutRoom, getBreakoutsResponse } from '../queries'; @@ -28,6 +30,13 @@ interface RoomManagmentStateProps { setFormIsValid: (isValid: boolean) => void; setRoomsRef: (rooms: Rooms) => void; setMoveRegisterRef: (moveRegister: moveUserRegistery) => void; + presentations: Presentation[]; + roomPresentations: RoomPresentations; + setRoomPresentations: React.Dispatch>; + currentPresentation: string; + currentSlidePrefix: string; + getRoomPresentation: (roomId: number) => string; + isUpdate: boolean; } const RoomManagmentState: React.FC = ({ @@ -38,6 +47,13 @@ const RoomManagmentState: React.FC = ({ runningRooms, setRoomsRef, setMoveRegisterRef, + presentations, + roomPresentations, + setRoomPresentations, + currentPresentation, + currentSlidePrefix, + getRoomPresentation, + isUpdate, }) => { const intl = useIntl(); const [selectedId, setSelectedId] = useState(''); @@ -226,6 +242,13 @@ const RoomManagmentState: React.FC = ({ randomlyAssign={randomlyAssign} resetRooms={resetRooms} users={users} + currentSlidePrefix={currentSlidePrefix} + presentations={presentations} + roomPresentations={roomPresentations} + setRoomPresentations={setRoomPresentations} + getRoomPresentation={getRoomPresentation} + currentPresentation={currentPresentation} + isUpdate={isUpdate} /> ) : null } diff --git a/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/room-managment-state/types.ts b/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/room-managment-state/types.ts index 2705135d1b..6e7e75b51e 100644 --- a/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/room-managment-state/types.ts +++ b/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/room-managment-state/types.ts @@ -26,6 +26,8 @@ export type RoomToWithSettings = { freeJoin: boolean; sequence: number; shortName: string; + allPages: boolean; + presId: string; }; export type Rooms = { @@ -45,4 +47,21 @@ export type ChildComponentProps = { randomlyAssign: () => void; resetRooms: (cap: number) => void; users: BreakoutUser[]; + currentSlidePrefix: string; + presentations: Presentation[]; + getRoomPresentation: (roomId: number) => string; + setRoomPresentations: React.Dispatch>; + currentPresentation: string; + roomPresentations: RoomPresentations; + isUpdate: boolean; +} + +export interface Presentation { + presentationId: string; + name: string; + current: boolean; +} + +export interface RoomPresentations { + [roomId: number]: string; } diff --git a/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/styles.ts b/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/styles.ts index 553a03f3bf..4121e83cd8 100644 --- a/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/breakout-room/create-breakout-room/styles.ts @@ -349,6 +349,15 @@ const SubTitle = styled.p` const Content = styled(FlexColumn)``; +const BreakoutSlideLabel = styled.label` + font-size: ${fontSizeSmall}; + font-weight: bolder; + display: flex; + align-items: center; + font-size: ${fontSizeSmall}; + margin-bottom: 0.2rem; +`; + export default { BoxContainer, Alert, @@ -380,4 +389,5 @@ export default { SubTitle, Content, ContentContainer, + BreakoutSlideLabel, }; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/alert/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/alert/component.tsx index bdd69207bd..e68e5795ad 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/alert/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/alert/component.tsx @@ -1,5 +1,4 @@ import React, { useCallback, useEffect, useRef } from 'react'; -import { useSubscription } from '@apollo/client'; import { isEqual } from 'radash'; import { defineMessages, useIntl } from 'react-intl'; import { layoutSelect, layoutSelectInput, layoutDispatch } from '/imports/ui/components/layout/context'; @@ -18,6 +17,7 @@ import { import ChatPushAlert from './push-alert/component'; import Styled from './styles'; import Service from './service'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const intlMessages = defineMessages({ appToastChatPublic: { @@ -54,10 +54,6 @@ const intlMessages = defineMessages({ }, }); -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id; -const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id; - const ALERT_DURATION = 4000; // 4 seconds interface ChatAlertContainerGraphqlProps { @@ -98,6 +94,10 @@ const ChatAlertGraphql: React.FC = (props) => { [idChatOpen, history.current], ); + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id; + const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id; + useEffect(() => { if (shouldRenderPublicChatAlerts) { publicUnreadMessages.forEach((m) => { @@ -192,11 +192,11 @@ const ChatAlertGraphql: React.FC = (props) => { const ChatAlertContainerGraphql: React.FC = (props) => { const cursor = useRef(new Date()); - const { data: publicMessages } = useSubscription( + const { data: publicMessages } = useDeduplicatedSubscription( CHAT_MESSAGE_PUBLIC_STREAM, { variables: { createdAt: cursor.current.toISOString() } }, ); - const { data: privateMessages } = useSubscription( + const { data: privateMessages } = useDeduplicatedSubscription( CHAT_MESSAGE_PRIVATE_STREAM, { variables: { createdAt: cursor.current.toISOString() } }, ); diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/alert/service.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/alert/service.ts index 72e61bde3b..ed7759e307 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/alert/service.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/alert/service.ts @@ -2,8 +2,7 @@ import AudioService from '/imports/ui/components/audio/service'; const playAlertSound = () => { AudioService.playAlertSound(`${window.meetingClientSettings.public.app.cdn - + window.meetingClientSettings.public.app.basename - + window.meetingClientSettings.public.app.instanceId}` + + window.meetingClientSettings.public.app.basename}` + '/resources/sounds/notify.mp3'); }; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/component.tsx index 688fde23ab..2e27057f66 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/component.tsx @@ -6,11 +6,11 @@ import { defineMessages, useIntl } from 'react-intl'; import BBBMenu from '/imports/ui/components/common/menu/component'; import { layoutSelect } from '/imports/ui/components/layout/context'; import { Layout } from '/imports/ui/components/layout/layoutTypes'; -import { useLazyQuery, useMutation } from '@apollo/client'; +import { useLazyQuery, useMutation, useQuery } from '@apollo/client'; import { uid } from 'radash'; import { isEmpty } from 'ramda'; import { - GET_CHAT_MESSAGE_HISTORY, GET_PERMISSIONS, getChatMessageHistory, getPermissions, + GET_CHAT_MESSAGE_HISTORY, getChatMessageHistory, } from './queries'; import Trigger from '/imports/ui/components/common/control-header/right/component'; import { generateExportedMessages } from './services'; @@ -18,10 +18,9 @@ import { getDateString } from '/imports/utils/string-utils'; import { ChatCommands } from '/imports/ui/core/enums/chat'; import { CHAT_PUBLIC_CLEAR_HISTORY } from './mutations'; import useMeetingSettings from '/imports/ui/core/local-states/useMeetingSettings'; - -// @ts-ignore - temporary, while meteor exists in the project -// const CHAT_CONFIG = window.meetingClientSettings.public.chat; -// const ENABLE_SAVE_AND_COPY_PUBLIC_CHAT = CHAT_CONFIG.enableSaveAndCopyPublicChat; +import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; +import useMeeting from '/imports/ui/core/hooks/useMeeting'; +import { GET_WELCOME_MESSAGE, WelcomeMsgsResponse } from '/imports/ui/components/chat/chat-graphql/chat-popup/queries'; const intlMessages = defineMessages({ clear: { @@ -66,6 +65,14 @@ const ChatActions: React.FC = () => { const [meetingIsBreakout, setMeetingIsBreakout] = useState(false); const [showShowWelcomeMessages, setShowShowWelcomeMessages] = useState(false); const [chatPublicClearHistory] = useMutation(CHAT_PUBLIC_CLEAR_HISTORY); + const { data: currentUserData, loading: currentUserLoading } = useCurrentUser((u) => ({ + isModerator: u.isModerator, + })); + const { data: meetingData, loading: meetingLoading } = useMeeting((m) => ({ + isBreakout: m.isBreakout, + name: m.name, + })); + const { data: welcomeData } = useQuery(GET_WELCOME_MESSAGE); const [ getChatMessageHistory, { @@ -73,13 +80,6 @@ const ChatActions: React.FC = () => { data: dataHistory, }] = useLazyQuery(GET_CHAT_MESSAGE_HISTORY, { fetchPolicy: 'no-cache' }); - const [ - getPermissions, - { - error: errorPermissions, - data: dataPermissions, - }] = useLazyQuery(GET_PERMISSIONS, { fetchPolicy: 'cache-and-network' }); - useEffect(() => { if (dataHistory) { const exportedString = generateExportedMessages( @@ -106,15 +106,24 @@ const ChatActions: React.FC = () => { }, [dataHistory]); useEffect(() => { - if (dataPermissions) { - setUserIsmoderator(dataPermissions.user_current[0].isModerator); - setMeetingIsBreakout(dataPermissions.meeting[0].isBreakout); - if (!isEmpty(dataPermissions.user_welcomeMsgs[0].welcomeMsg || '') - || !isEmpty(dataPermissions.user_welcomeMsgs[0].welcomeMsgForModerators || '')) { + if (currentUserData) { + setUserIsmoderator(!!currentUserData.isModerator); + } + if (meetingData) { + setMeetingIsBreakout(!!meetingData.isBreakout); + } + }, [currentUserData, meetingData]); + + useEffect(() => { + if (welcomeData) { + if ( + !isEmpty(welcomeData.user_welcomeMsgs[0]?.welcomeMsg || '') + || !isEmpty(welcomeData.user_welcomeMsgs[0]?.welcomeMsgForModerators || '') + ) { setShowShowWelcomeMessages(true); } } - }, [dataPermissions]); + }, [welcomeData]); const actions = useMemo(() => { const dropdownActions = [ @@ -143,15 +152,18 @@ const ChatActions: React.FC = () => { }, { key: uniqueIdsRef.current[2], - enable: userIsModerator && !meetingIsBreakout, + enable: true, + disabled: !userIsModerator || meetingIsBreakout, icon: 'delete', dataTest: 'chatClear', label: intl.formatMessage(intlMessages.clear), onClick: () => chatPublicClearHistory(), + loading: currentUserLoading || meetingLoading, }, { key: uniqueIdsRef.current[3], - enable: showShowWelcomeMessages, + enable: true, + disabled: !showShowWelcomeMessages, icon: 'about', dataTest: 'restoreWelcomeMessages', label: intl.formatMessage(intlMessages.showWelcomeMessage), @@ -159,10 +171,11 @@ const ChatActions: React.FC = () => { const restoreWelcomeMessagesEvent = new CustomEvent(ChatCommands.RESTORE_WELCOME_MESSAGES); window.dispatchEvent(restoreWelcomeMessagesEvent); }, + loading: currentUserLoading, }, ]; return dropdownActions.filter((action) => action.enable); - }, [userIsModerator, meetingIsBreakout, showShowWelcomeMessages]); + }, [userIsModerator, meetingIsBreakout, showShowWelcomeMessages, currentUserLoading, meetingLoading]); if (errorHistory) { return (

@@ -171,15 +184,7 @@ const ChatActions: React.FC = () => {

); } - if (errorPermissions) { - return ( -

- Error loading permissions: - {' '} - {JSON.stringify(errorPermissions)} -

- ); - } + return ( { aria-label={intl.formatMessage(intlMessages.options)} hideLabel icon="more" - onClick={() => { - getPermissions(); - }} data-test="chatOptionsMenu" + onClick={() => {}} /> )} opts={{ diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/queries.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/queries.ts index d15baa1137..2b396dc759 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/queries.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/queries.ts @@ -1,6 +1,5 @@ /* eslint-disable camelcase */ import { gql } from '@apollo/client'; -import { User } from '/imports/ui/Types/user'; import { Meeting } from '/imports/ui/Types/meeting'; import { Message } from '/imports/ui/Types/message'; @@ -10,12 +9,6 @@ export type getChatMessageHistory = { user_welcomeMsgs: Array<{welcomeMsg: string, welcomeMsgForModerators: string | null}>; }; -export type getPermissions = { - user_current: Array; - meeting: Array<{ isBreakout: boolean }>; - user_welcomeMsgs: Array<{ welcomeMsg: string; welcomeMsgForModerators: string | null }>; -}; - export const GET_CHAT_MESSAGE_HISTORY = gql` query getChatMessageHistory { chat_message_public(order_by: {createdAt: asc}) { @@ -41,19 +34,3 @@ query getChatMessageHistory { } } `; - -export const GET_PERMISSIONS = gql` - query getPermissions { - user_current { - isModerator - } - meeting { - isBreakout - name - } - user_welcomeMsgs { - welcomeMsg - welcomeMsgForModerators - } - } -`; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/services.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/services.ts index 4c399829b8..fea700dc2f 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/services.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/chat-actions/services.ts @@ -34,8 +34,10 @@ export const generateExportedMessages = ( intl: IntlShape, ): string => { const welcomeMessage = htmlDecode(welcomeSettings.welcomeMsg); - const modOnlyMessage = welcomeSettings.welcomeMsgForModerators && htmlDecode(welcomeSettings.welcomeMsgForModerators); - const systemMessages = `${welcomeMessage ? `system: ${welcomeMessage}` : ''}\n ${modOnlyMessage ? `system: ${modOnlyMessage}` : ''}\n`; + const welcomeMsgForModerators = welcomeSettings.welcomeMsgForModerators + && htmlDecode(welcomeSettings.welcomeMsgForModerators); + const systemMessages = `${welcomeMessage ? `system: ${welcomeMessage}` : ''}\n + ${welcomeMsgForModerators ? `system: ${welcomeMsgForModerators}` : ''}\n`; const text = messages.reduce((acc, message) => { const date = new Date(message.createdAt); diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/component.tsx index a9780313f2..2503e0202d 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/component.tsx @@ -75,7 +75,7 @@ const ChatHeader: React.FC = ({ icon: 'close', label: intl.formatMessage(intlMessages.closeChatLabel, { 0: title }), onClick: () => { - updateVisible({ variables: { chatId } }); + updateVisible({ variables: { chatId, visible: false } }); closePrivateChat(chatId); layoutContextDispatch({ type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/queries.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/queries.ts index 6f94928b14..1beddccffd 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/queries.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-header/queries.ts @@ -25,9 +25,10 @@ export const GET_CHAT_DATA = gql` `; export const CLOSE_PRIVATE_CHAT_MUTATION = gql` - mutation UpdateChatUser($chatId: String) { - update_chat_user(where: { chatId: { _eq: $chatId } }, _set: { visible: false }) { - affected_rows - } + mutation UpdateChatVisible($chatId: String, $visible: Boolean) { + chatSetVisible( + chatId: $chatId + visible: $visible + ) } `; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-form/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-form/component.tsx index eb23e0527d..69a4067e9a 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-form/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-form/component.tsx @@ -14,9 +14,10 @@ import { ChatFormUiDataPayloads } from 'bigbluebutton-html-plugin-sdk/dist/cjs/u import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; import { layoutSelect } from '/imports/ui/components/layout/context'; import { defineMessages, useIntl } from 'react-intl'; -import { isChatEnabled } from '/imports/ui/services/features'; -import ClickOutside from '/imports/ui/components/click-outside/component'; +import { useIsChatEnabled } from '/imports/ui/services/features'; import { checkText } from 'smile2emoji'; +import { findDOMNode } from 'react-dom'; + import Styled from './styles'; import deviceInfo from '/imports/utils/deviceInfo'; import usePreviousValue from '/imports/ui/hooks/usePreviousValue'; @@ -37,12 +38,8 @@ import Storage from '/imports/ui/services/storage/session'; import { indexOf, without } from '/imports/utils/array-utils'; import { GraphqlDataHookSubscriptionResponse } from '/imports/ui/Types/hook'; import { throttle } from '/imports/utils/throttle'; +import logger from '/imports/startup/client/logger'; -// @ts-ignore - temporary, while meteor exists in the project -const CHAT_CONFIG = window.meetingClientSettings.public.chat; - -const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id; -const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id; const CLOSED_CHAT_LIST_KEY = 'closedChatList'; const START_TYPING_THROTTLE_INTERVAL = 1000; @@ -59,7 +56,6 @@ interface ChatMessageFormProps { locked: boolean, partnerIsLoggedOut: boolean, title: string, - handleClickOutside: () => void, } const messages = defineMessages({ @@ -82,6 +78,9 @@ const messages = defineMessages({ errorMaxMessageLength: { id: 'app.chat.errorMaxMessageLength', }, + errorOnSendMessage: { + id: 'app.chat.errorOnSendMessage', + }, errorServerDisconnected: { id: 'app.chat.disconnected', }, @@ -114,14 +113,7 @@ const messages = defineMessages({ }, }); -// @ts-ignore - temporary, while meteor exists in the project -const AUTO_CONVERT_EMOJI = window.meetingClientSettings.public.chat.autoConvertEmoji; -// @ts-ignore - temporary, while meteor exists in the project -const ENABLE_EMOJI_PICKER = window.meetingClientSettings.public.chat.emojiPicker.enable; -const ENABLE_TYPING_INDICATOR = CHAT_CONFIG.typingIndicator.enabled; - const ChatMessageForm: React.FC = ({ - handleClickOutside, title, disabled, partnerIsLoggedOut, @@ -132,12 +124,15 @@ const ChatMessageForm: React.FC = ({ locked, isRTL, }) => { - if (!isChatEnabled()) return null; + const isChatEnabled = useIsChatEnabled(); + if (!isChatEnabled) return null; const intl = useIntl(); const [hasErrors, setHasErrors] = React.useState(false); const [error, setError] = React.useState(null); const [message, setMessage] = React.useState(''); const [showEmojiPicker, setShowEmojiPicker] = React.useState(false); + const emojiPickerRef = useRef(null); + const emojiPickerButtonRef = useRef(null); const [isTextAreaFocused, setIsTextAreaFocused] = React.useState(false); const textAreaRef: RefObject = useRef(null); const { isMobile } = deviceInfo; @@ -157,6 +152,13 @@ const ChatMessageForm: React.FC = ({ loading: chatSendMessageLoading, error: chatSendMessageError, }] = useMutation(CHAT_SEND_MESSAGE); + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id; + const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id; + const AUTO_CONVERT_EMOJI = window.meetingClientSettings.public.chat.autoConvertEmoji; + const ENABLE_EMOJI_PICKER = window.meetingClientSettings.public.chat.emojiPicker.enable; + const ENABLE_TYPING_INDICATOR = CHAT_CONFIG.typingIndicator.enabled; + const handleUserTyping = (hasError?: boolean) => { if (hasError || !ENABLE_TYPING_INDICATOR) return; @@ -288,7 +290,7 @@ const ChatMessageForm: React.FC = ({ const msg = textToMarkdown(message); - if (msg.length < minMessageLength) return; + if (msg.length < minMessageLength || chatSendMessageLoading) return; if (disabled || msg.length > maxMessageLength) { @@ -296,13 +298,14 @@ const ChatMessageForm: React.FC = ({ return; } - chatSendMessage({ - variables: { - chatMessageInMarkdownFormat: msg, - chatId: chatId === PUBLIC_CHAT_ID ? PUBLIC_GROUP_CHAT_ID : chatId, - }, - }); - + if (!chatSendMessageLoading) { + chatSendMessage({ + variables: { + chatMessageInMarkdownFormat: msg, + chatId: chatId === PUBLIC_CHAT_ID ? PUBLIC_GROUP_CHAT_ID : chatId, + }, + }); + } const currentClosedChats = Storage.getItem(CLOSED_CHAT_LIST_KEY); // Remove the chat that user send messages from the session. @@ -328,7 +331,6 @@ const ChatMessageForm: React.FC = ({ bubbles: true, cancelable: true, }); - handleSubmit(event); } }; @@ -388,7 +390,30 @@ const ChatMessageForm: React.FC = ({ } }); - if (chatSendMessageError) { return
something went wrong
; } + useEffect(() => { + if (chatSendMessageError && error == null) { + logger.debug('Error on sending chat message: ', chatSendMessageError?.message); + setError(intl.formatMessage(messages.errorOnSendMessage)); + } + }, [chatSendMessageError]); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + // eslint-disable-next-line react/no-find-dom-node + const button = findDOMNode(emojiPickerButtonRef.current); + if ( + (emojiPickerRef.current && !emojiPickerRef.current.contains(event.target as Node)) + && (button && !button.contains(event.target as Node)) + ) { + setShowEmojiPicker(false); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, []); return ( = ({ isRTL={isRTL} > {showEmojiPicker ? ( - + handleEmojiSelect(emojiObject)} showPreview={false} @@ -415,7 +440,7 @@ const ChatMessageForm: React.FC = ({ autoCorrect="off" autoComplete="off" spellCheck="true" - disabled={disabled || partnerIsLoggedOut || chatSendMessageLoading} + disabled={disabled || partnerIsLoggedOut} value={message} onFocus={() => { window.dispatchEvent(new CustomEvent(PluginSdk.ChatFormUiDataNames.CHAT_INPUT_IS_FOCUSED, { @@ -431,7 +456,6 @@ const ChatMessageForm: React.FC = ({ value: false, }, })); - setIsTextAreaFocused(false); }} onChange={handleMessageChange} onKeyDown={handleMessageKeyDown} @@ -442,6 +466,7 @@ const ChatMessageForm: React.FC = ({ /> {ENABLE_EMOJI_PICKER ? ( setShowEmojiPicker(!showEmojiPicker)} icon="happy" color="light" @@ -468,9 +493,9 @@ const ChatMessageForm: React.FC = ({ { error && ( - + {error} - + ) } @@ -478,13 +503,7 @@ const ChatMessageForm: React.FC = ({ ); }; - return ENABLE_EMOJI_PICKER ? ( - handleClickOutside()} - > - {renderForm()} - - ) : renderForm(); + return renderForm(); }; // eslint-disable-next-line no-empty-pattern @@ -492,7 +511,6 @@ const ChatMessageFormContainer: React.FC = ({ // connected, move to network status }) => { const intl = useIntl(); - const [showEmojiPicker, setShowEmojiPicker] = React.useState(false); const idChatOpen: string = layoutSelect((i: Layout) => i.idChatOpen); const isRTL = layoutSelect((i: Layout) => i.isRTL); const { data: chat } = useChat((c: Partial) => ({ @@ -530,30 +548,25 @@ const ChatMessageFormContainer: React.FC = ({ } } - const handleClickOutside = () => { - if (showEmojiPicker) { - setShowEmojiPicker(false); - } - }; - - if (chat?.participant && !chat.participant.isOnline) { + if (chat?.participant && !chat.participant.currentlyInMeeting) { return ; } + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + return ( diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-form/styles.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-form/styles.ts index dd51f55570..9ab78446e2 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-form/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-form/styles.ts @@ -119,6 +119,15 @@ const EmojiButton = styled(Button)` `; const EmojiPickerWrapper = styled.div` +position: absolute; +bottom: calc(100% + 0.5rem); +left: 0; +right: 0; +border: 1px solid ${colorGrayLighter}; +border-radius: ${borderRadius}; +box-shadow: 0 2px 10px rgba(0,0,0,0.1); +z-index: 1000; + .emoji-mart { max-width: 100% !important; } @@ -136,7 +145,7 @@ const EmojiPickerWrapper = styled.div` } `; -const Error = styled.div` +const ChatMessageError = styled.div` color: ${colorDanger}; font-size: calc(${fontSizeBase} * .75); color: ${colorGrayDark}; @@ -148,7 +157,9 @@ const Error = styled.div` margin-left: 0.05rem; `; -const EmojiPicker = styled(EmojiPickerComponent)``; +const EmojiPicker = styled(EmojiPickerComponent)` + position: relative; +`; export default { Form, @@ -159,5 +170,5 @@ export default { EmojiButtonWrapper, EmojiPicker, EmojiPickerWrapper, - Error, + ChatMessageError, }; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/component.tsx index ac613843fb..c1be7d67c2 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/component.tsx @@ -28,10 +28,6 @@ import { import useReactiveRef from '/imports/ui/hooks/useReactiveRef'; import useStickyScroll from '/imports/ui/hooks/useStickyScroll'; -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_id; -const PUBLIC_GROUP_CHAT_KEY = CHAT_CONFIG.public_group_id; - const PAGE_SIZE = 50; const intlMessages = defineMessages({ @@ -58,7 +54,6 @@ interface ChatListProps { }, } ) => void; - lastSeenAt: string; } const isElement = (el: unknown): el is HTMLElement => { @@ -114,7 +109,6 @@ const ChatMessageList: React.FC = ({ totalPages, chatId, setMessageAsSeenMutation, - lastSeenAt, totalUnread, isRTL, }) => { @@ -299,7 +293,6 @@ const ChatMessageList: React.FC = ({ chatId={chatId} markMessageAsSeen={markMessageAsSeen} scrollRef={messageListRef} - lastSeenAt={lastSeenAt} /> ); }) @@ -324,6 +317,11 @@ const ChatMessageList: React.FC = ({ const ChatMessageListContainer: React.FC = () => { const idChatOpen = layoutSelect((i: Layout) => i.idChatOpen); const isRTL = layoutSelect((i: Layout) => i.isRTL); + + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_id; + const PUBLIC_GROUP_CHAT_KEY = CHAT_CONFIG.public_group_id; + const isPublicChat = idChatOpen === PUBLIC_CHAT_KEY; const chatId = !isPublicChat ? idChatOpen : PUBLIC_GROUP_CHAT_KEY; const { data: currentChat } = useChat((chat) => { @@ -341,7 +339,6 @@ const ChatMessageListContainer: React.FC = () => { const totalPages = Math.ceil(totalMessages / PAGE_SIZE); return ( > scrollRef: React.RefObject; markMessageAsSeen: (message: Message) => void; + messageReadFeedbackEnabled: boolean; } const intlMessages = defineMessages({ @@ -62,6 +65,7 @@ const ChatMesssage: React.FC = ({ message, setMessagesRequestedFromPlugin, markMessageAsSeen, + messageReadFeedbackEnabled, }) => { const intl = useIntl(); const markMessageAsSeenOnScrollEnd = useCallback(() => { @@ -101,10 +105,14 @@ const ChatMesssage: React.FC = ({ }, [message, messageRef, markMessageAsSeenOnScrollEnd]); if (!message) return null; - - const sameSender = (previousMessage?.user?.userId - || lastSenderPreviousPage) === message?.user?.userId; + const pluginMessageNotCustom = (previousMessage?.messageType !== ChatMessageType.PLUGIN + || !JSON.parse(previousMessage?.messageMetadata).custom); + const sameSender = ((previousMessage?.user?.userId + || lastSenderPreviousPage) === message?.user?.userId) && pluginMessageNotCustom; const isSystemSender = message.messageType === ChatMessageType.BREAKOUT_ROOM; + const currentPluginMessageMetadata = message.messageType === ChatMessageType.PLUGIN + && JSON.parse(message.messageMetadata); + const isCustomPluginMessage = currentPluginMessageMetadata.custom; const dateTime = new Date(message?.createdAt); const formattedTime = intl.formatTime(dateTime, { hour: 'numeric', @@ -161,6 +169,20 @@ const ChatMesssage: React.FC = ({ ), }; case ChatMessageType.BREAKOUT_ROOM: + return { + name: message.senderName, + color: '#0F70D7', + isModerator: true, + isSystemSender: true, + component: ( + + ), + }; + case ChatMessageType.API: return { name: message.senderName, color: '#0F70D7', @@ -177,12 +199,13 @@ const ChatMesssage: React.FC = ({ case ChatMessageType.USER_AWAY_STATUS_MSG: { const { away } = JSON.parse(message.messageMetadata); const awayMessage = (away) - ? `${msgTime} ${message.senderName} ${intl.formatMessage(intlMessages.userAway)}` - : `${msgTime} ${message.senderName} ${intl.formatMessage(intlMessages.userNotAway)}`; + ? `${intl.formatMessage(intlMessages.userAway)}` + : `${intl.formatMessage(intlMessages.userNotAway)}`; return { name: message.senderName, - color: '', - isModerator: false, + color: '#0F70D7', + isModerator: true, + isSystemSender: true, component: ( = ({ ), }; } + case ChatMessageType.PLUGIN: { + return { + name: message.user?.name, + color: message.user?.color, + isModerator: message.user?.isModerator, + isSystemSender: false, + component: currentPluginMessageMetadata.custom + ? (<>) + : ( + + ), + }; + } case ChatMessageType.TEXT: default: return { @@ -215,37 +255,50 @@ const ChatMesssage: React.FC = ({ sameSender={sameSender} ref={messageRef} isPresentationUpload={messageContent.isPresentationUpload} + isCustomPluginMessage={isCustomPluginMessage} > - {(!message?.user || !sameSender) && ( + {((!message?.user || !sameSender) && ( message.messageType !== ChatMessageType.USER_AWAY_STATUS_MSG - && message.messageType !== ChatMessageType.CHAT_CLEAR) && ( - - {!messageContent.avatarIcon ? ( - !message.user || (message.user?.avatar.length === 0 ? messageContent.name.toLowerCase().slice(0, 2) : '') - ) : ( - - )} - + && message.messageType !== ChatMessageType.API + && message.messageType !== ChatMessageType.CHAT_CLEAR + && !isCustomPluginMessage) + ) && ( + + {!messageContent.avatarIcon ? ( + !message.user || (message.user?.avatar.length === 0 ? messageContent.name.toLowerCase().slice(0, 2) : '') + ) : ( + + )} + )} - {message.messageType !== ChatMessageType.USER_AWAY_STATUS_MSG - && message.messageType !== ChatMessageType.CHAT_CLEAR && ( + {message.messageType !== ChatMessageType.CHAT_CLEAR + && !isCustomPluginMessage + && ( - )} - {messageContent.component} + )} + + {messageContent.component} + {messageReadFeedbackEnabled && ( + + )} + ); diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/poll-content/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/poll-content/component.tsx index 25f2fd56d3..f39f3f6eb3 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/poll-content/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/poll-content/component.tsx @@ -8,6 +8,7 @@ import Styled from './styles'; interface ChatPollContentProps { metadata: string; + height?: number; } interface Metadata { @@ -75,6 +76,7 @@ function assertAsMetadata(metadata: unknown): asserts metadata is Metadata { const ChatPollContent: React.FC = ({ metadata: string, + height = undefined, }) => { const intl = useIntl(); @@ -92,13 +94,13 @@ const ChatPollContent: React.FC = ({ }; }); - const height = translatedAnswers.length * 50; + const useHeight = height || translatedAnswers.length * 50; return ( -
+ {pollData.questionText} - + = ({ -
+ ); }; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/poll-content/styles.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/poll-content/styles.ts index 53d2d84332..f9c8606452 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/poll-content/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/poll-content/styles.ts @@ -11,6 +11,11 @@ export const PollText = styled.div` word-break: break-word; `; +export const PollWrapper = styled.div` + width: 100%; +`; + export default { PollText, + PollWrapper, }; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/presentation-content/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/presentation-content/component.tsx index 61f6df95aa..483aeb560e 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/presentation-content/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/presentation-content/component.tsx @@ -2,10 +2,6 @@ import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; import Styled from './styles'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore - temporary, while meteor exists in the project -const APP_CONFIG = window.meetingClientSettings.public.app; - interface ChatMessagePresentationContentProps { metadata: string; } @@ -44,6 +40,10 @@ const ChatMessagePresentationContent: React.FC { const substrings = filename.split('.'); diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/text-content/styles.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/text-content/styles.ts index b953e77bd0..fe14ccd20f 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/text-content/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-content/text-content/styles.ts @@ -21,7 +21,6 @@ export const ChatMessage = styled.div` ${({ systemMsg }) => systemMsg && ` background: ${systemMessageBackgroundColor}; border: 1px solid ${systemMessageBorderColor}; - border-radius: 1rem; font-weight: ${btnFontWeight}; padding: ${fontSizeBase}; text-color: #1f252b; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-header/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-header/component.tsx index 0572a69811..ded8cc1217 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-header/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-header/component.tsx @@ -11,7 +11,7 @@ const intlMessages = defineMessages({ interface ChatMessageHeaderProps { name: string; - isOnline: boolean; + currentlyInMeeting: boolean; dateTime: Date; sameSender: boolean; } @@ -19,7 +19,7 @@ interface ChatMessageHeaderProps { const ChatMessageHeader: React.FC = ({ sameSender, name, - isOnline, + currentlyInMeeting, dateTime, }) => { const intl = useIntl(); @@ -28,11 +28,11 @@ const ChatMessageHeader: React.FC = ({ return ( - + {name} { - isOnline ? null : ( + currentlyInMeeting ? null : ( {`(${intl.formatMessage(intlMessages.offline)})`} diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-header/styles.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-header/styles.ts index 61478b0c42..38fe27d5af 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-header/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-header/styles.ts @@ -8,7 +8,7 @@ import { import { lineHeightComputed } from '/imports/ui/stylesheets/styled-components/typography'; interface ChatUserNameProps { - isOnline: boolean; + currentlyInMeeting: boolean; } export const HeaderContent = styled.div` @@ -31,11 +31,11 @@ export const ChatUserName = styled.div` overflow: hidden; text-overflow: ellipsis; - ${({ isOnline }) => isOnline && ` + ${({ currentlyInMeeting }) => currentlyInMeeting && ` color: ${colorHeading}; `} - ${({ isOnline }) => !isOnline && ` + ${({ currentlyInMeeting }) => !currentlyInMeeting && ` text-transform: capitalize; font-style: italic; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-read-confirmation/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-read-confirmation/component.tsx new file mode 100644 index 0000000000..2034909d20 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-read-confirmation/component.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { useIntl, defineMessages } from 'react-intl'; +import { Message } from '/imports/ui/Types/message'; +import Auth from '/imports/ui/services/auth'; +import Tooltip from '/imports/ui/components/common/tooltip/component'; +import { ReadIcon, IconWrapper } from './styles'; + +const intlMessages = defineMessages({ + messageReadLabel: { + id: 'app.chat.messageRead', + description: 'Label for the message read indicator', + }, +}); + +interface MessageReadConfirmationProps { + message: Message; +} + +const CONFIRMATION_READ_ICON = 'check'; + +const MessageReadConfirmation: React.FC = ({ + message, +}) => { + const intl = useIntl(); + const isFromMe = Auth.userID === message?.user?.userId; + + if (!isFromMe || !message.recipientHasSeen) return null; + + return ( + + + + + + ); +}; + +export default MessageReadConfirmation; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-read-confirmation/styles.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-read-confirmation/styles.ts new file mode 100644 index 0000000000..c26349c91d --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/message-read-confirmation/styles.ts @@ -0,0 +1,14 @@ +import styled from 'styled-components'; +import { + colorPrimary, +} from '/imports/ui/stylesheets/styled-components/palette'; +import Icon from '/imports/ui/components/common/icon/icon-ts/component'; + +export const ReadIcon = styled(Icon)` + color: ${colorPrimary}; +`; + +export const IconWrapper = styled.span` + display: flex; + align-items: center; +`; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/styles.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/styles.ts index 89c145074a..95274606c8 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/chat-message/styles.ts @@ -22,10 +22,12 @@ interface ChatWrapperProps { sameSender: boolean; isSystemSender: boolean; isPresentationUpload?: boolean; + isCustomPluginMessage: boolean; } interface ChatContentProps { sameSender: boolean; + isCustomPluginMessage: boolean; } interface ChatAvatarProps { @@ -68,6 +70,10 @@ export const ChatWrapper = styled.div` border-radius: 0px 3px 3px 0px; padding: 8px 2px; `} + ${({ isCustomPluginMessage }) => isCustomPluginMessage && ` + margin: 0; + padding: 0; + `} `; export const ChatContent = styled.div` @@ -75,7 +81,8 @@ export const ChatContent = styled.div` flex-flow: column; width: 100%; - ${({ sameSender }) => sameSender && ` + ${({ sameSender, isCustomPluginMessage }) => sameSender + && !isCustomPluginMessage && ` margin-left: 2.6rem; `} `; @@ -157,7 +164,7 @@ export const ChatAvatar = styled.div` // ================ image ================ // ================ content ================ - color: ${colorWhite}; + color: ${colorWhite} !important; font-size: 110%; text-transform: capitalize; display: flex; @@ -170,3 +177,8 @@ export const ChatAvatar = styled.div` width: 2.25rem; } `; + +export const MessageItemWrapper = styled.div` + display: flex; + flex-direction: row; +`; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/component.tsx index 94d31f7262..1a3cf1366e 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-message-list/page/component.tsx @@ -16,17 +16,11 @@ import { useCreateUseSubscription } from '/imports/ui/core/hooks/createUseSubscr import { setLoadedMessageGathering } from '/imports/ui/core/hooks/useLoadedChatMessages'; import { ChatLoading } from '../../component'; -// @ts-ignore - temporary, while meteor exists in the project -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_GROUP_CHAT_KEY = CHAT_CONFIG.public_group_id; - interface ChatListPageContainerProps { page: number; pageSize: number; setLastSender: (page: number, message: string) => void; lastSenderPreviousPage: string | undefined; - // eslint-disable-next-line react/no-unused-prop-types - lastSeenAt: string, chatId: string; markMessageAsSeen: (message: Message) => void; scrollRef: React.RefObject; @@ -34,6 +28,7 @@ interface ChatListPageContainerProps { interface ChatListPageProps { messages: Array; + messageReadFeedbackEnabled: boolean; lastSenderPreviousPage: string | undefined; page: number; markMessageAsSeen: (message: Message)=> void; @@ -42,6 +37,7 @@ interface ChatListPageProps { const ChatListPage: React.FC = ({ messages, + messageReadFeedbackEnabled, lastSenderPreviousPage, page, markMessageAsSeen, @@ -66,8 +62,8 @@ const ChatListPage: React.FC = ({ return ( // eslint-disable-next-line react/jsx-filename-extension
- {messages.map((message, index, Array) => { - const previousMessage = Array[index - 1]; + {messages.map((message, index, messagesArray) => { + const previousMessage = messagesArray[index - 1]; return ( = ({ } scrollRef={scrollRef} markMessageAsSeen={markMessageAsSeen} + messageReadFeedbackEnabled={messageReadFeedbackEnabled} /> ); })} @@ -95,6 +92,11 @@ const ChatListPageContainer: React.FC = ({ markMessageAsSeen, scrollRef, }) => { + // @ts-ignore - temporary, while meteor exists in the project + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_GROUP_CHAT_KEY = CHAT_CONFIG.public_group_id; + const PRIVATE_MESSAGE_READ_FEEDBACK_ENABLED = CHAT_CONFIG.privateMessageReadFeedback.enabled; + const isPublicChat = chatId === PUBLIC_GROUP_CHAT_KEY; const chatQuery = isPublicChat ? CHAT_MESSAGE_PUBLIC_SUBSCRIPTION @@ -102,6 +104,7 @@ const ChatListPageContainer: React.FC = ({ const defaultVariables = { offset: (page) * pageSize, limit: pageSize }; const variables = isPublicChat ? defaultVariables : { ...defaultVariables, requestedChatId: chatId }; + const isPrivateReadFeedbackEnabled = !isPublicChat && PRIVATE_MESSAGE_READ_FEEDBACK_ENABLED; const useChatMessageSubscription = useCreateUseSubscription(chatQuery, variables, true); const { @@ -125,6 +128,7 @@ const ChatListPageContainer: React.FC = ({ ` `} padding-bottom: ${smPaddingX}; + user-select: text; `; export const MessageList = styled(ScrollboxVertical)` @@ -42,6 +43,7 @@ export const MessageList = styled(ScrollboxVertical)` padding-top: 0; outline-style: none; overflow-x: hidden; + user-select: none; [dir='rtl'] & { margin: 0 0 0 auto; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-popup/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-popup/component.tsx index 35cd501073..b75de4ccc9 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-popup/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-popup/component.tsx @@ -15,9 +15,6 @@ interface ChatPopupProps { const WELCOME_MSG_KEY = 'welcomeMsg'; const WELCOME_MSG_FOR_MODERATORS_KEY = 'welcomeMsgForModerators'; -// @ts-ignore - temporary, while meteor exists in the project -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_GROUP_CHAT_KEY = CHAT_CONFIG.public_group_id; const setWelcomeMsgsOnSession = (key: string, value: boolean) => { sessionStorage.setItem(key, String(value)); @@ -96,6 +93,9 @@ const ChatPopupContainer: React.FC = () => { error: welcomeError, } = useQuery(GET_WELCOME_MESSAGE); const idChatOpen = layoutSelect((i: Layout) => i.idChatOpen); + + const PUBLIC_GROUP_CHAT_KEY = window.meetingClientSettings.public.chat.public_group_id; + if (idChatOpen !== PUBLIC_GROUP_CHAT_KEY) return null; if (welcomeLoading) return null; diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-typing-indicator/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-typing-indicator/component.tsx index 94f327a6d5..9bbea89a5b 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-typing-indicator/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-typing-indicator/component.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { useSubscription } from '@apollo/client'; import { IS_TYPING_PUBLIC_SUBSCRIPTION, IS_TYPING_PRIVATE_SUBSCRIPTION, @@ -19,15 +18,10 @@ import useChat from '/imports/ui/core/hooks/useChat'; import useMeeting from '/imports/ui/core/hooks/useMeeting'; import { Chat } from '/imports/ui/Types/chat'; import { GraphqlDataHookSubscriptionResponse } from '/imports/ui/Types/hook'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const DEBUG_CONSOLE = false; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore - temporary, while meteor exists in the project -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_GROUP_CHAT_KEY = CHAT_CONFIG.public_group_id; -const TYPING_INDICATOR_ENABLED = CHAT_CONFIG.typingIndicator.enabled; - interface TypingIndicatorProps { typingUsers: Array, intl: IntlShape, @@ -149,6 +143,10 @@ const TypingIndicatorContainer: React.FC = () => { } } + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_GROUP_CHAT_KEY = CHAT_CONFIG.public_group_id; + const TYPING_INDICATOR_ENABLED = CHAT_CONFIG.typingIndicator.enabled; + // eslint-disable-next-line no-unused-expressions, no-console DEBUG_CONSOLE && console.log('TypingIndicatorContainer:chat', chat); const typingQuery = idChatOpen === PUBLIC_GROUP_CHAT_KEY ? IS_TYPING_PUBLIC_SUBSCRIPTION @@ -156,7 +154,7 @@ const TypingIndicatorContainer: React.FC = () => { const { data: typingUsersData, error: typingUsersError, - } = useSubscription(typingQuery, { + } = useDeduplicatedSubscription(typingQuery, { variables: { chatId: idChatOpen, }, diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/component.tsx index 39fd1d686b..0ff783aa00 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/component.tsx @@ -21,6 +21,24 @@ interface ChatProps { const Chat: React.FC = ({ isRTL }) => { const { isChrome } = browserInfo; + + React.useEffect(() => { + const handleMouseDown = () => { + if (window.getSelection) { + const selection = window.getSelection(); + if (selection) { + selection.removeAllRanges(); + } + } + }; + + document.addEventListener('mousedown', handleMouseDown); + + return () => { + document.removeEventListener('mousedown', handleMouseDown); + }; + }, []); + return ( @@ -30,7 +48,6 @@ const Chat: React.FC = ({ isRTL }) => { ); }; - export const ChatLoading: React.FC = ({ isRTL }) => { const { isChrome } = browserInfo; return ( diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/styles.ts b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/styles.ts index a2743fb24d..02160fa6c2 100644 --- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/styles.ts @@ -18,6 +18,7 @@ export const Chat = styled.div` justify-content: space-around; overflow: hidden; height: 100%; + user-select: none; ${({ isRTL }) => isRTL && ` padding-left: 0.1rem; @@ -70,6 +71,8 @@ const ChatContent = styled.div` display: contents; `; -const ChatMessages = styled.div``; +const ChatMessages = styled.div` + user-select: text; +`; export default { Chat, ChatMessages, ChatContent }; diff --git a/bigbluebutton-html5/imports/ui/components/common/button/button-emoji/ButtonEmoji.jsx b/bigbluebutton-html5/imports/ui/components/common/button/button-emoji/ButtonEmoji.jsx index 13a3710fb3..75e50d7323 100644 --- a/bigbluebutton-html5/imports/ui/components/common/button/button-emoji/ButtonEmoji.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/button/button-emoji/ButtonEmoji.jsx @@ -28,32 +28,22 @@ const propTypes = { rotate: PropTypes.bool, }; -const defaultProps = { - emoji: '', - label: '', - onKeyDown: null, - onFocus: null, - tabIndex: -1, - hideLabel: false, - onClick: null, - className: '', - rotate: false, -}; - const ButtonEmoji = (props) => { const { - hideLabel, - className, + hideLabel = false, + className = '', hidden, - rotate, + rotate = false, ...newProps } = props; const { - emoji, - label, - tabIndex, - onClick, + emoji = '', + label = '', + tabIndex = -1, + onClick = null, + onKeyDown = null, + onFocus = null, } = newProps; const IconComponent = (); @@ -68,6 +58,9 @@ const ButtonEmoji = (props) => { {...newProps} aria-label={label} onClick={onClick} + onKeyDown={onKeyDown} + onFocus={onFocus} + className={className} > { !hideLabel && label } @@ -82,4 +75,3 @@ const ButtonEmoji = (props) => { export default ButtonEmoji; ButtonEmoji.propTypes = propTypes; -ButtonEmoji.defaultProps = defaultProps; diff --git a/bigbluebutton-html5/imports/ui/components/common/button/component.jsx b/bigbluebutton-html5/imports/ui/components/common/button/component.jsx index aa9f56d6d6..abdc7bb0f6 100755 --- a/bigbluebutton-html5/imports/ui/components/common/button/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/button/component.jsx @@ -54,6 +54,13 @@ const propTypes = { */ icon: PropTypes.string, + /** + * Defines the button svg icon + * @defaultValue undefined + */ + + svgIcon: PropTypes.string, + /** * Defines the button icon is on the right side * @defaultValue false @@ -73,6 +80,12 @@ const propTypes = { * @defaultvalue undefined */ customIcon: PropTypes.node, + + /** + * Defines the buttom loading state + * @defaultValue false + */ + loading: PropTypes.bool, }; const defaultProps = { @@ -85,12 +98,14 @@ const defaultProps = { iconRight: false, hideLabel: false, tooltipLabel: '', + loading: false, }; export default class Button extends BaseButton { _cleanProps(otherProps) { const remainingProps = Object.assign({}, otherProps); delete remainingProps.icon; + delete remainingProps.svgIcon; delete remainingProps.customIcon; delete remainingProps.size; delete remainingProps.color; @@ -154,6 +169,7 @@ export default class Button extends BaseButton { ghost, circle, block, + loading, ...otherProps } = this.props; @@ -168,6 +184,7 @@ export default class Button extends BaseButton { block={block} className={className} iconRight={iconRight} + loading={loading} {...remainingProps} > {this.renderIcon()} @@ -186,6 +203,7 @@ export default class Button extends BaseButton { ghost, circle, block, + loading, ...otherProps } = this.props; @@ -199,6 +217,7 @@ export default class Button extends BaseButton { ghost={ghost} circle={circle} block={block} + loading={loading} {...remainingProps} > {this.renderButtonEmojiSibling()} @@ -229,9 +248,14 @@ export default class Button extends BaseButton { renderIcon() { const { icon: iconName, + svgIcon, customIcon, } = this.props; + if (svgIcon) { + return (); + } + if (iconName) { return (); } if (customIcon) { diff --git a/bigbluebutton-html5/imports/ui/components/common/button/styles.js b/bigbluebutton-html5/imports/ui/components/common/button/styles.js index d1f71f31d5..6cdd84ae32 100644 --- a/bigbluebutton-html5/imports/ui/components/common/button/styles.js +++ b/bigbluebutton-html5/imports/ui/components/common/button/styles.js @@ -1,5 +1,7 @@ import styled from 'styled-components'; import Icon from '/imports/ui/components/common/icon/component'; +import SvgIcon from '/imports/ui/components/common/icon-svg/component'; + import { btnSpacing, borderRadius, @@ -80,6 +82,30 @@ const ButtonIcon = styled(Icon)` } `; +const ButtonSvgIcon = styled(SvgIcon)` + width: 1em; + height: 1em; + text-align: center; + background: red; + + &:before { + width: 1em; + height: 1em; + } + + .buttonWrapper & { + font-size: 125%; + } + + & + span { + margin: 0 0 0 ${btnSpacing}; + + [dir="rtl"] & { + margin: 0 ${btnSpacing} 0 0; + } + } +`; + const EmojiButtonSibling = styled.span` position: absolute; width: 100%; @@ -289,6 +315,39 @@ const ButtonWrapper = styled(BaseButton)` background-color: transparent; } `} + ${({ loading }) => loading && ` + &::before { + position: relative; + border: 5px solid transparent; + border-radius: 50%; + background-color: #3498db; + color: white; + font-size: 16px; + text-align: center; + line-height: 90px; + cursor: pointer; + } + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 50%; + border: 2px solid white; + border-top-color: transparent; + animation: spin 1.5s linear infinite; + } + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } +`} `; const ButtonSpan = styled.span` @@ -1215,6 +1274,7 @@ const Button = styled(BaseButton)` export default { ButtonIcon, + ButtonSvgIcon, EmojiButtonSibling, ButtonLabel, ButtonWrapper, diff --git a/bigbluebutton-html5/imports/ui/components/common/checkbox/base.jsx b/bigbluebutton-html5/imports/ui/components/common/checkbox/base.jsx index 8d08c4fb75..cb65b7c06e 100644 --- a/bigbluebutton-html5/imports/ui/components/common/checkbox/base.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/checkbox/base.jsx @@ -1,6 +1,5 @@ import React, { createRef, PureComponent } from 'react'; import PropTypes from 'prop-types'; -import { findDOMNode } from 'react-dom'; const propTypes = { disabled: PropTypes.bool, @@ -33,18 +32,18 @@ export default class Base extends PureComponent { } componentDidMount() { - const element = findDOMNode(this.element.current); + const element = this.element.current; if (element) element.addEventListener('keydown', this.handleKeyDown); } componentWillUnmount() { - const element = findDOMNode(this.element.current); + const element = this.element.current; if (element) element.removeEventListener('keydown', this.handleKeyDown); } handleKeyDown(event) { const { key } = event; - const node = findDOMNode(this.element.current); + const node = this.element.current; if (key === 'Enter' && node) { const input = node.getElementsByTagName('input')[0]; input?.click(); diff --git a/bigbluebutton-html5/imports/ui/components/common/error-boundary/component.jsx b/bigbluebutton-html5/imports/ui/components/common/error-boundary/component.jsx index f62521cdf6..c2d38512ba 100644 --- a/bigbluebutton-html5/imports/ui/components/common/error-boundary/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/error-boundary/component.jsx @@ -1,10 +1,12 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import logger, { generateLoggerStreams } from '/imports/startup/client/logger'; +import apolloContextHolder from '/imports/ui/core/graphql/apolloContextHolder/apolloContextHolder'; +import { ApolloLink } from '@apollo/client'; const propTypes = { children: PropTypes.element.isRequired, - Fallback: PropTypes.element, + Fallback: PropTypes.func, errorMessage: PropTypes.string, logMetadata: PropTypes.shape({ logCode: PropTypes.string, @@ -28,9 +30,9 @@ class ErrorBoundary extends Component { } componentDidMount() { - const data = JSON.parse((sessionStorage.getItem('clientStartupSettings')) || {}); + const data = window.meetingClientSettings.public; const logConfig = data?.clientLog; - if (logConfig) { + if (logConfig && logger?.streams.length === 0) { generateLoggerStreams(logConfig).forEach((stream) => { logger.addStream(stream); }); @@ -53,6 +55,27 @@ class ErrorBoundary extends Component { } componentDidCatch(error, errorInfo) { + window.dispatchEvent(new Event('StopAudioTracks')); + const data = window.meetingClientSettings.public.media; + const mediaElement = document.querySelector(data?.mediaTag || '#remote-media'); + if (mediaElement) { + mediaElement.pause(); + mediaElement.srcObject = null; + } + const apolloClient = apolloContextHolder.getClient(); + + if (apolloClient) { + apolloClient.stop(); + } + + const ws = apolloContextHolder.getLink(); + if (ws) { + // delay to termintate the connection, for user receive the end eject message + setTimeout(() => { + apolloClient.setLink(ApolloLink.empty()); + ws.terminate(); + }, 5000); + } this.setState({ error, errorInfo, diff --git a/bigbluebutton-html5/imports/ui/components/common/fallback-errors/fallback-view/component.jsx b/bigbluebutton-html5/imports/ui/components/common/fallback-errors/fallback-view/component.jsx index 030a8ee820..d8ee96b744 100644 --- a/bigbluebutton-html5/imports/ui/components/common/fallback-errors/fallback-view/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/fallback-errors/fallback-view/component.jsx @@ -27,13 +27,14 @@ const propTypes = { }), }; -const defaultProps = { - error: { - message: '', - }, +const defaultError = { + message: '', }; -const FallbackView = ({ error, intl }) => ( +const FallbackView = ({ + error = defaultError, + intl, +}) => ( {intl.formatMessage(intlMessages.title)} @@ -57,6 +58,5 @@ const FallbackView = ({ error, intl }) => ( ); FallbackView.propTypes = propTypes; -FallbackView.defaultProps = defaultProps; export default injectIntl(FallbackView); diff --git a/bigbluebutton-html5/imports/ui/components/common/fullscreen-button/component.jsx b/bigbluebutton-html5/imports/ui/components/common/fullscreen-button/component.jsx index 22c8af77c0..0908146442 100755 --- a/bigbluebutton-html5/imports/ui/components/common/fullscreen-button/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/fullscreen-button/component.jsx @@ -30,32 +30,21 @@ const propTypes = { fullScreenStyle: PropTypes.bool, }; -const defaultProps = { - dark: false, - bottom: false, - isIphone: false, - isFullscreen: false, - elementName: '', - color: 'default', - fullScreenStyle: true, - fullscreenRef: null, -}; - const FullscreenButtonComponent = ({ intl, - dark, - bottom, - elementName, + dark = false, + bottom = false, + elementName = '', elementId, elementGroup, - isIphone, - isFullscreen, + isIphone = false, + isFullscreen = false, layoutContextDispatch, currentElement, currentGroup, - color, - fullScreenStyle, - fullscreenRef, + color = 'default', + fullScreenStyle = true, + fullscreenRef = null, handleToggleFullScreen, }) => { if (isIphone) return null; @@ -105,6 +94,5 @@ const FullscreenButtonComponent = ({ }; FullscreenButtonComponent.propTypes = propTypes; -FullscreenButtonComponent.defaultProps = defaultProps; export default injectIntl(FullscreenButtonComponent); diff --git a/bigbluebutton-html5/imports/ui/components/common/icon-svg/component.tsx b/bigbluebutton-html5/imports/ui/components/common/icon-svg/component.tsx new file mode 100644 index 0000000000..93c9c781b7 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/common/icon-svg/component.tsx @@ -0,0 +1,33 @@ +import React, { memo } from 'react'; +import Styled from './styles'; + +interface IconProps { + iconName: string; + rotate?: boolean; +} + +const iconsMap: { [key: string]: JSX.Element } = { + reactions: ( + + + + + ), +}; + +const Icon: React.FC = ({ + iconName = '', + rotate = false, +}) => { + if (!iconsMap[iconName]) { + return null; + } + + return ( + + {iconsMap[iconName]} + + ); +}; + +export default memo(Icon); diff --git a/bigbluebutton-html5/imports/ui/components/common/icon-svg/styles.ts b/bigbluebutton-html5/imports/ui/components/common/icon-svg/styles.ts new file mode 100644 index 0000000000..134010d3cb --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/common/icon-svg/styles.ts @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +type IconProps = { + $rotate: boolean; +}; + +const Icon = styled.i` + ${({ $rotate }) => $rotate && ` + transform: rotate(180deg); + `} + display: flex; +`; + +export default { + Icon, +}; diff --git a/bigbluebutton-html5/imports/ui/components/common/icon/component.jsx b/bigbluebutton-html5/imports/ui/components/common/icon/component.jsx index 6889700835..7f817a883a 100644 --- a/bigbluebutton-html5/imports/ui/components/common/icon/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/icon/component.jsx @@ -12,19 +12,12 @@ const propTypes = { color: PropTypes.string, }; -const defaultProps = { - prependIconName: 'icon-bbb-', - rotate: false, - className: '', - color: undefined, -}; - const Icon = ({ - className, - prependIconName, + className = '', + prependIconName = 'icon-bbb-', iconName, - rotate, - color, + rotate = false, + color = undefined, ...props }) => ( = ({ - className, - prependIconName, - iconName, + className = '', + prependIconName = 'icon-bbb-', + iconName = '', rotate = false, }) => ( = ({ /> ); -Icon.defaultProps = defaultProps; - export default memo(Icon); diff --git a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx index c4b185439f..1479cb46d1 100644 --- a/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx @@ -5,7 +5,7 @@ import { Divider } from "@mui/material"; import Icon from "/imports/ui/components/common/icon/component"; import { SMALL_VIEWPORT_BREAKPOINT } from '/imports/ui/components/layout/enums'; import KEY_CODES from '/imports/utils/keyCodes'; - +import MenuSkeleton from './skeleton'; import Styled from './styles'; const intlMessages = defineMessages({ @@ -102,7 +102,7 @@ class BBBMenu extends React.Component { return actions?.map(a => { const { dataTest, label, onClick, key, disabled, - description, selected, textColor, isToggle } = a; + description, selected, textColor, isToggle, loading } = a; const emojiSelected = key?.toLowerCase()?.includes(selectedEmoji?.toLowerCase()); let customStyles = { @@ -117,6 +117,13 @@ class BBBMenu extends React.Component { if (a.customStyles) { customStyles = { ...customStyles, ...a.customStyles }; } + + if (loading) { + return ( + + ); + } + return [ (!a.isSeparator && onClick) && ( { - onClick(); + onClick(event); const close = !keepOpen && !key?.includes('setstatus') && !key?.includes('back'); // prevent menu close for sub menu actions if (close) this.handleClose(event); diff --git a/bigbluebutton-html5/imports/ui/components/common/menu/skeleton.tsx b/bigbluebutton-html5/imports/ui/components/common/menu/skeleton.tsx new file mode 100644 index 0000000000..4b390fa1b8 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/common/menu/skeleton.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; +import Styled from './styles'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; + +const MenuSkeleton: React.FC = () => { + const Settings = getSettingsSingletonInstance(); + // @ts-ignore + const { isRTL } = Settings.application; + + return ( + + + + + + + + ); +}; + +export default MenuSkeleton; diff --git a/bigbluebutton-html5/imports/ui/components/common/menu/styles.js b/bigbluebutton-html5/imports/ui/components/common/menu/styles.js index 5f6959f025..6f5055f81c 100644 --- a/bigbluebutton-html5/imports/ui/components/common/menu/styles.js +++ b/bigbluebutton-html5/imports/ui/components/common/menu/styles.js @@ -134,6 +134,16 @@ const BBBMenuItem = styled(MenuItem)` `} `; +const Skeleton = styled.div` + padding: 12px 16px; + font-size: 0.9em !important; + line-height: 1; +`; + +const SkeletonWrapper = styled.span` + width: 100%; +`; + export default { MenuWrapper, MenuItemWrapper, @@ -142,4 +152,6 @@ export default { IconRight, BBBMenuItem, BBBMenuInformation, + Skeleton, + SkeletonWrapper, }; diff --git a/bigbluebutton-html5/imports/ui/components/common/modal/confirmation/component.jsx b/bigbluebutton-html5/imports/ui/components/common/modal/confirmation/component.jsx index ae6eb3ec85..039a1a88f0 100644 --- a/bigbluebutton-html5/imports/ui/components/common/modal/confirmation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/modal/confirmation/component.jsx @@ -18,12 +18,14 @@ const propTypes = { confirmButtonColor: PropTypes.string, disableConfirmButton: PropTypes.bool, description: PropTypes.string, + hideConfirmButton: PropTypes.bool, }; const defaultProps = { confirmButtonColor: 'primary', disableConfirmButton: false, description: '', + hideConfirmButton: false, }; class ConfirmationModal extends Component { @@ -46,6 +48,8 @@ class ConfirmationModal extends Component { checkboxMessageId, confirmButtonColor, confirmButtonLabel, + cancelButtonLabel, + hideConfirmButton, confirmButtonDataTest, confirmParam, disableConfirmButton, @@ -92,18 +96,20 @@ class ConfirmationModal extends Component { - { - onConfirm(confirmParam, checked); - setIsOpen(false); - }} - /> + {!hideConfirmButton && ( + { + onConfirm(confirmParam, checked); + setIsOpen(false); + }} + /> + )} setIsOpen(false)} /> diff --git a/bigbluebutton-html5/imports/ui/components/common/remaining-time/breakout-duration/component.tsx b/bigbluebutton-html5/imports/ui/components/common/remaining-time/breakout-duration/component.tsx index 592abe6561..b96b175a23 100644 --- a/bigbluebutton-html5/imports/ui/components/common/remaining-time/breakout-duration/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/common/remaining-time/breakout-duration/component.tsx @@ -1,9 +1,9 @@ import React from 'react'; import RemainingTime from '/imports/ui/components/common/remaining-time/component'; import { defineMessages, useIntl } from 'react-intl'; -import { useSubscription } from '@apollo/client'; import { FIRST_BREAKOUT_DURATION_DATA_SUBSCRIPTION, breakoutDataResponse } from './queries'; import logger from '/imports/startup/client/logger'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const intlMessages = defineMessages({ calculatingBreakoutTimeRemaining: { @@ -36,7 +36,7 @@ const BreakoutRemainingTimeContainer: React.FC(FIRST_BREAKOUT_DURATION_DATA_SUBSCRIPTION); + } = useDeduplicatedSubscription(FIRST_BREAKOUT_DURATION_DATA_SUBSCRIPTION); if (breakoutLoading) return loadingRemainingTime(); if (!breakoutData) return null; diff --git a/bigbluebutton-html5/imports/ui/components/common/remaining-time/component.tsx b/bigbluebutton-html5/imports/ui/components/common/remaining-time/component.tsx index cc98da62a5..faae56bb12 100644 --- a/bigbluebutton-html5/imports/ui/components/common/remaining-time/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/common/remaining-time/component.tsx @@ -20,14 +20,6 @@ interface RemainingTimeProps { alertLabel?: intlMsg; } -const defaultProps = { - endingLabel: undefined, - alertLabel: undefined, -}; - -const METEOR_SETTINGS_APP = window.meetingClientSettings.public.app; -const REMAINING_TIME_ALERT_THRESHOLD_ARRAY: number[] = METEOR_SETTINGS_APP.remainingTimeAlertThresholdArray; - let lastAlertTime: number | null = null; const RemainingTime: React.FC = (props) => { @@ -35,8 +27,8 @@ const RemainingTime: React.FC = (props) => { referenceStartedTime, durationInSeconds, durationLabel, - endingLabel, - alertLabel, + endingLabel = undefined, + alertLabel = undefined, isBreakout, boldText, } = props; @@ -80,6 +72,9 @@ const RemainingTime: React.FC = (props) => { if (remainingTime >= 0 && timeRemainingInterval) { if (remainingTime > 0) { + const APP_SETTINGS = window.meetingClientSettings.public.app; + const REMAINING_TIME_ALERT_THRESHOLD_ARRAY: number[] = APP_SETTINGS.remainingTimeAlertThresholdArray; + const alertsInSeconds = REMAINING_TIME_ALERT_THRESHOLD_ARRAY.map((item) => item * 60); if (alertsInSeconds.includes(remainingTime) && remainingTime !== lastAlertTime && alertLabel) { @@ -126,6 +121,4 @@ const RemainingTime: React.FC = (props) => { ); }; -RemainingTime.defaultProps = defaultProps; - export default RemainingTime; diff --git a/bigbluebutton-html5/imports/ui/components/common/switch/component.jsx b/bigbluebutton-html5/imports/ui/components/common/switch/component.jsx index 2d05e4acdb..801293c421 100644 --- a/bigbluebutton-html5/imports/ui/components/common/switch/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/switch/component.jsx @@ -1,7 +1,7 @@ import React from 'react'; import Toggle from 'react-toggle'; import { defineMessages, injectIntl } from 'react-intl'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import Styled from './styles'; const intlMessages = defineMessages({ @@ -35,6 +35,7 @@ class Switch extends Toggle { ...inputProps } = this.props; + const Settings = getSettingsSingletonInstance(); const { animations } = Settings.application; const { diff --git a/bigbluebutton-html5/imports/ui/components/common/toast/component.jsx b/bigbluebutton-html5/imports/ui/components/common/toast/component.jsx index e582797734..c35f77db54 100755 --- a/bigbluebutton-html5/imports/ui/components/common/toast/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/toast/component.jsx @@ -10,10 +10,6 @@ const propTypes = { type: PropTypes.oneOf(Object.values(toast.TYPE)).isRequired, }; -const defaultProps = { - icon: null, -}; - const defaultIcons = { [toast.TYPE.INFO]: 'help', [toast.TYPE.SUCCESS]: 'checkmark', @@ -23,7 +19,7 @@ const defaultIcons = { }; const Toast = ({ - icon, + icon = null, type, message, content, @@ -53,4 +49,3 @@ const Toast = ({ export default Toast; Toast.propTypes = propTypes; -Toast.defaultProps = defaultProps; diff --git a/bigbluebutton-html5/imports/ui/components/common/toast/container.jsx b/bigbluebutton-html5/imports/ui/components/common/toast/container.jsx index ba94c8ff22..946b547409 100755 --- a/bigbluebutton-html5/imports/ui/components/common/toast/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/toast/container.jsx @@ -1,6 +1,6 @@ import React from 'react'; import Styled from './styles'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; class ToastContainer extends React.Component { // we never want this component to update since will break Toastify @@ -9,6 +9,7 @@ class ToastContainer extends React.Component { } render() { + const Settings = getSettingsSingletonInstance(); const { animations } = Settings.application; return ( diff --git a/bigbluebutton-html5/imports/ui/components/common/tooltip/component.jsx b/bigbluebutton-html5/imports/ui/components/common/tooltip/component.jsx index e809a86acf..27254e9163 100755 --- a/bigbluebutton-html5/imports/ui/components/common/tooltip/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/tooltip/component.jsx @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import { ESCAPE } from '/imports/utils/keyCodes'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import Tippy, { roundArrow } from 'tippy.js'; import 'tippy.js/dist/svg-arrow.css'; import 'tippy.js/animations/shift-away.css'; @@ -61,8 +61,9 @@ class Tooltip extends Component { placement, } = this.props; + const Settings = getSettingsSingletonInstance(); const { animations } = Settings.application; - + const overridePlacement = placement ? placement : position; let overrideDelay; if (animations) { @@ -104,6 +105,7 @@ class Tooltip extends Component { } componentDidUpdate() { + const Settings = getSettingsSingletonInstance(); const { animations } = Settings.application; const { title } = this.props; const elements = document.querySelectorAll('[id^="tippy-"]'); diff --git a/bigbluebutton-html5/imports/ui/components/common/tooltip/container.jsx b/bigbluebutton-html5/imports/ui/components/common/tooltip/container.jsx index df9a29b669..d5e80f721a 100644 --- a/bigbluebutton-html5/imports/ui/components/common/tooltip/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/common/tooltip/container.jsx @@ -1,10 +1,9 @@ import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; import FullscreenService from '/imports/ui/components/common/fullscreen-button/service'; import Tooltip from './component'; -const TooltipContainer = props => ; +const TooltipContainer = (props) => ( + +); -export default withTracker(() => ({ - fullscreen: FullscreenService.getFullscreenElement(), -}))(TooltipContainer); +export default TooltipContainer; diff --git a/bigbluebutton-html5/imports/ui/components/components-data/graphqlToMiniMongoAdapterManager/component.tsx b/bigbluebutton-html5/imports/ui/components/components-data/graphqlToMiniMongoAdapterManager/component.tsx deleted file mode 100644 index fcb70eba69..0000000000 --- a/bigbluebutton-html5/imports/ui/components/components-data/graphqlToMiniMongoAdapterManager/component.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React, { - useCallback, - useMemo, - useRef, - useState, -} from 'react'; - -import UserGrapQlMiniMongoAdapter from '/imports/ui/components/components-data/userGrapQlMiniMongoAdapter/component'; -import VoiceUserGrapQlMiniMongoAdapter from '/imports/ui/components/components-data/voiceUserGraphQlMiniMongoAdapter/component'; -import MeetingGrapQlMiniMongoAdapter from '/imports/ui/components/components-data/meetingGrapQlMiniMongoAdapter/component'; -import ScreenShareGraphQlMiniMongoAdapterContainer from '/imports/ui/components/components-data/screenshareGraphQlMiniMongoAdapter/component'; -import VideoStreamAdapter from '/imports/ui/components/video-provider/video-provider-graphql/adapter'; - -interface GraphqlToMiniMongoAdapterManagerProps { - children: React.ReactNode; -} - -export interface AdapterProps extends GraphqlToMiniMongoAdapterManagerProps { - onReady: (key:string) => void; -} - -const GraphqlToMiniMongoAdapterManager: React.FC = ({ children }) => { - const [adapterLoaded, setAdapterLoaded] = useState(false); - const loadedComponents = useRef<{ - [key: string]: number; - }>({}); - const adapterComponents = useRef([ - UserGrapQlMiniMongoAdapter, - MeetingGrapQlMiniMongoAdapter, - VideoStreamAdapter, - VoiceUserGrapQlMiniMongoAdapter, - ]); - - const onReady = useCallback((key: string) => { - loadedComponents.current[key] = 1; - if (Object.keys(loadedComponents.current).length >= adapterComponents.current.length) { - setAdapterLoaded(true); - } - }, []); - - const nestAdapters = useMemo(() => { - return adapterComponents.current.reduce((acc, Component) => ( - - {acc} - - ), ); - }, []); - return ( - <> - {/* screenshare loads conditionally so can't be used on lock loading */} - - {nestAdapters} - {adapterLoaded ? children : null} - - ); -}; - -export default GraphqlToMiniMongoAdapterManager; diff --git a/bigbluebutton-html5/imports/ui/components/components-data/meetingGrapQlMiniMongoAdapter/component.tsx b/bigbluebutton-html5/imports/ui/components/components-data/meetingGrapQlMiniMongoAdapter/component.tsx deleted file mode 100644 index 39c7479503..0000000000 --- a/bigbluebutton-html5/imports/ui/components/components-data/meetingGrapQlMiniMongoAdapter/component.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { useEffect, useRef } from 'react'; -import { useCreateUseSubscription } from '/imports/ui/core/hooks/createUseSubscription'; -import MEETING_SUBSCRIPTION from '/imports/ui/core/graphql/queries/meetingSubscription'; -import { Meeting } from '/imports/ui/Types/meeting'; -import Meetings from '/imports/api/meetings'; -import { AdapterProps } from '../graphqlToMiniMongoAdapterManager/component'; - -const MeetingGrapQlMiniMongoAdapter: React.FC = ({ - onReady, - children, -}) => { - const ready = useRef(false); - const meetingSubscription = useCreateUseSubscription(MEETING_SUBSCRIPTION, {}, true); - const { - data: meetingData, - } = meetingSubscription(); - - useEffect(() => { - if (meetingData) { - if (!ready.current) { - ready.current = true; - onReady('MeetingGrapQlMiniMongoAdapter'); - } - const meeting = JSON.parse(JSON.stringify(meetingData[0])); - const { meetingId } = meeting; - Meetings.upsert({ meetingId }, meeting); - } - }, [meetingData]); - return children; -}; - -export default MeetingGrapQlMiniMongoAdapter; diff --git a/bigbluebutton-html5/imports/ui/components/components-data/plugin-context/context.tsx b/bigbluebutton-html5/imports/ui/components/components-data/plugin-context/context.tsx index b4c63884a6..fa66d76dc6 100644 --- a/bigbluebutton-html5/imports/ui/components/components-data/plugin-context/context.tsx +++ b/bigbluebutton-html5/imports/ui/components/components-data/plugin-context/context.tsx @@ -10,6 +10,7 @@ export const PluginsContextProvider = ({ children, ...props }: any) => { {} as ExtensibleArea, ); const [domElementManipulationMessageIds, setDomElementManipulationMessageIds] = useState([]); + const [domElementManipulationStreamIds, setDomElementManipulationStreamIds] = useState([]); return ( { pluginsExtensibleAreasAggregatedState, domElementManipulationMessageIds, setDomElementManipulationMessageIds, + domElementManipulationStreamIds, + setDomElementManipulationStreamIds, }} > {children} diff --git a/bigbluebutton-html5/imports/ui/components/components-data/plugin-context/types.ts b/bigbluebutton-html5/imports/ui/components/components-data/plugin-context/types.ts index 095a2a284e..486f89e5d1 100644 --- a/bigbluebutton-html5/imports/ui/components/components-data/plugin-context/types.ts +++ b/bigbluebutton-html5/imports/ui/components/components-data/plugin-context/types.ts @@ -21,4 +21,7 @@ export interface PluginsContextType { domElementManipulationMessageIds: string[]; setDomElementManipulationMessageIds: React.Dispatch< React.SetStateAction>; + domElementManipulationStreamIds: string[]; + setDomElementManipulationStreamIds: React.Dispatch< + React.SetStateAction>; } diff --git a/bigbluebutton-html5/imports/ui/components/components-data/screenshareGraphQlMiniMongoAdapter/component.tsx b/bigbluebutton-html5/imports/ui/components/components-data/screenshareGraphQlMiniMongoAdapter/component.tsx deleted file mode 100644 index 72df0f3341..0000000000 --- a/bigbluebutton-html5/imports/ui/components/components-data/screenshareGraphQlMiniMongoAdapter/component.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React, { useEffect } from 'react'; -import useMeeting from '/imports/ui/core/hooks/useMeeting'; -import Screenshare from '/imports/api/screenshare'; -import { useCreateUseSubscription } from '/imports/ui/core/hooks/createUseSubscription'; -import { ScreenshareType, getScreenShareData } from './queries'; - -interface ScreenShareGraphQlMiniMongoAdapterProps { - meetingId: string; -} - -const ScreenShareGraphQlMiniMongoAdapter: React.FC = ({ - meetingId, -}) => { - const screenshareSubscription = useCreateUseSubscription(getScreenShareData, {}, true); - const { - data: screenshareData, - } = screenshareSubscription(); - - useEffect(() => { - if (screenshareData) { - const screenshare = JSON.parse(JSON.stringify(screenshareData[0] || '{}')); - const { screenshareId } = screenshare; - Screenshare.upsert({ screenshareId }, { - meetingId, - screenshare: { - ...screenshare, - }, - screenshareId, - }); - } - return () => { - Screenshare.remove({ meetingId }); - }; - }, [screenshareData]); - return null; -}; - -const ScreenShareGraphQlMiniMongoAdapterContainer: React.FC = () => { - const { - data: currentMeeting, - } = useMeeting((m) => ({ - componentsFlags: m.componentsFlags, - meetingId: m.meetingId, - })); - const hasCurrentscreenshare = currentMeeting?.componentsFlags?.hasScreenshare ?? false; - return hasCurrentscreenshare ? ( - - ) : null; -}; - -export default ScreenShareGraphQlMiniMongoAdapterContainer; diff --git a/bigbluebutton-html5/imports/ui/components/components-data/userGrapQlMiniMongoAdapter/component.tsx b/bigbluebutton-html5/imports/ui/components/components-data/userGrapQlMiniMongoAdapter/component.tsx deleted file mode 100644 index 5730eb29b9..0000000000 --- a/bigbluebutton-html5/imports/ui/components/components-data/userGrapQlMiniMongoAdapter/component.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { useSubscription } from '@apollo/client'; -import React, { useEffect, useRef, useState } from 'react'; -import CURRENT_USER_SUBSCRIPTION from '/imports/ui/core/graphql/queries/currentUserSubscription'; -import { User } from '/imports/ui/Types/user'; -import Users from '/imports/api/users'; -import logger from '/imports/startup/client/logger'; -import { AdapterProps } from '../graphqlToMiniMongoAdapterManager/component'; - -interface UserCurrentResponse { - user_current: Array; -} - -const UserGrapQlMiniMongoAdapter: React.FC = ({ - onReady, - children, -}) => { - const ready = useRef(false); - const { - error, - data, - } = useSubscription(CURRENT_USER_SUBSCRIPTION); - const [userDataSetted, setUserDataSetted] = useState(false); - - useEffect(() => { - if (error) { - logger.error('Error in UserGrapQlMiniMongoAdapter', error); - } - }, [error]); - - useEffect(() => { - if (data && data.user_current) { - if (!ready.current) { - ready.current = true; - onReady('UserGrapQlMiniMongoAdapter'); - } - const { userId } = data.user_current[0]; - Users.upsert({ userId }, data.user_current[0]); - if (!userDataSetted) { - setUserDataSetted(true); - } - } - }, [data]); - return children; -}; - -export default UserGrapQlMiniMongoAdapter; diff --git a/bigbluebutton-html5/imports/ui/components/components-data/voiceUserGraphQlMiniMongoAdapter/component.tsx b/bigbluebutton-html5/imports/ui/components/components-data/voiceUserGraphQlMiniMongoAdapter/component.tsx deleted file mode 100644 index c25ef662f1..0000000000 --- a/bigbluebutton-html5/imports/ui/components/components-data/voiceUserGraphQlMiniMongoAdapter/component.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { useSubscription } from '@apollo/client'; -import React, { useEffect, useRef, useState } from 'react'; -import VoiceUsers from '/imports/api/voice-users/'; -import logger from '/imports/startup/client/logger'; -import { UserVoiceStreamResponse, voiceUserStream } from './queries'; -import { AdapterProps } from '../graphqlToMiniMongoAdapterManager/component'; - -const VoiceUserGrapQlMiniMongoAdapter: React.FC = ({ - onReady, - children, -}) => { - const ready = useRef(false); - const { - loading, - error, - data, - } = useSubscription(voiceUserStream); - const [voiceUserDataSetted, setVoiceUserDataSetted] = useState(false); - useEffect(() => { - if (error) { - logger.error('Error in VoiceUserGrapQlMiniMongoAdapter', error); - } - }, [error]); - - useEffect(() => { - if (data && data.user_voice_mongodb_adapter_stream) { - const usersVoice = data.user_voice_mongodb_adapter_stream; - - usersVoice.forEach((userVoice) => { - VoiceUsers.upsert({ userId: userVoice.userId }, userVoice); - }); - } - }, [data]); - - useEffect(() => { - if (loading) { - // loading turns false only first audio join of the meeting, probably because it's a stream - if (!ready.current) { - ready.current = true; - onReady('VoiceUserGrapQlMiniMongoAdapter'); - } - if (!voiceUserDataSetted) { - setVoiceUserDataSetted(true); - } - } - }, [loading]); - return children; -}; - -export default VoiceUserGrapQlMiniMongoAdapter; diff --git a/bigbluebutton-html5/imports/ui/components/components-data/voiceUserGraphQlMiniMongoAdapter/queries.ts b/bigbluebutton-html5/imports/ui/components/components-data/voiceUserGraphQlMiniMongoAdapter/queries.ts deleted file mode 100644 index f9dda72a5b..0000000000 --- a/bigbluebutton-html5/imports/ui/components/components-data/voiceUserGraphQlMiniMongoAdapter/queries.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { gql } from '@apollo/client'; - -interface UserVoiceStream { - callerName: string | null; - callerNum: string | null; - callingWith: string | null; - endTime: string | null; - endedAt: string | null; - floor: string | null; - hideTalkingIndicatorAt: string | null; - joined: string | null; - lastFloorTime: string | null; - lastSpeakChangedAt: number; - listenOnly: string | null; - muted: string | null; - showTalkingIndicator: boolean; - spoke: string | null; - startTime: string | null; - startedAt: string | null; - talking: string | null; - userId: string; - voiceConf: string | null; - voiceConfCallSession: string | null; - voiceConfCallState: string | null; - voiceConfClientSession: string | null; - voiceUpdatedAt: string | null; - voiceUserId: string | null; -} - -export interface UserVoiceStreamResponse { - user_voice_mongodb_adapter_stream: UserVoiceStream[]; -} - -export const voiceUserStream = gql` - subscription voiceUserStream { - user_voice_mongodb_adapter_stream(cursor: {initial_value: {voiceUpdatedAt: "2020-01-01"}}, batch_size: 100) { - callerName - callerNum - callingWith - endTime - endedAt - floor - hideTalkingIndicatorAt - joined - lastFloorTime - lastSpeakChangedAt - listenOnly - muted - showTalkingIndicator - spoke - startTime - startedAt - talking - userId - voiceConf - voiceConfCallSession - voiceConfCallState - voiceConfClientSession - voiceUpdatedAt - voiceUserId - } - } -`; - -export default { - voiceUserStream, -}; diff --git a/bigbluebutton-html5/imports/ui/components/connection-manager/component.tsx b/bigbluebutton-html5/imports/ui/components/connection-manager/component.tsx index 46654e9eb8..6d0b9a9314 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-manager/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/connection-manager/component.tsx @@ -1,27 +1,21 @@ import { ApolloClient, ApolloProvider, InMemoryCache, NormalizedCacheObject, ApolloLink, } from '@apollo/client'; -import { WebSocketLink } from '@apollo/client/link/ws'; -import { SubscriptionClient } from 'subscriptions-transport-ws'; -import React, { useContext, useEffect } from 'react'; +import { GraphQLWsLink } from '@apollo/client/link/subscriptions'; +import { createClient } from 'graphql-ws'; +import { onError } from '@apollo/client/link/error'; +import React, { useContext, useEffect, useRef } from 'react'; import { LoadingContext } from '/imports/ui/components/common/loading-screen/loading-screen-HOC/component'; import logger from '/imports/startup/client/logger'; import apolloContextHolder from '../../core/graphql/apolloContextHolder/apolloContextHolder'; +import connectionStatus from '../../core/graphql/singletons/connectionStatus'; +import deviceInfo from '/imports/utils/deviceInfo'; +import BBBWeb from '/imports/api/bbb-web-api'; interface ConnectionManagerProps { children: React.ReactNode; } -interface Response { - response: { - returncode: string; - version: string; - apiVersion: string; - bbbVersion: string; - graphqlWebsocketUrl: string; - } -} - const DEFAULT_MAX_MUTATION_PAYLOAD_SIZE = 10485760; // 10MB const getMaxMutationPayloadSize = () => window.meetingClientSettings?.public?.app?.maxMutationPayloadSize ?? DEFAULT_MAX_MUTATION_PAYLOAD_SIZE; @@ -48,29 +42,76 @@ const payloadSizeCheckLink = new ApolloLink((operation, forward) => { return forward(operation); }); +const errorLink = onError(({ graphQLErrors, networkError }) => { + if (graphQLErrors) { + graphQLErrors.forEach(({ message }) => { + logger.error(`[GraphQL error]: Message: ${message}`); + }); + } + + if (networkError) { + logger.error(`[Network error]: ${networkError}`); + } +}); + const ConnectionManager: React.FC = ({ children }): React.ReactNode => { const [graphqlUrlApolloClient, setApolloClient] = React.useState | null>(null); const [graphqlUrl, setGraphqlUrl] = React.useState(''); const loadingContextInfo = useContext(LoadingContext); + const numberOfAttempts = useRef(20); + const [errorCounts, setErrorCounts] = React.useState(0); + const activeSocket = useRef(); + const tsLastMessageRef = useRef(0); + const tsLastPingMessageRef = useRef(0); + const boundary = useRef(15_000); + const [terminalError, setTerminalError] = React.useState(''); useEffect(() => { - fetch(`https://${window.location.hostname}/bigbluebutton/api`, { - headers: { - 'Content-Type': 'application/json', - }, - }).then(async (response) => { - const responseJson: Response = await response.json(); - setGraphqlUrl(responseJson.response.graphqlWebsocketUrl); + BBBWeb.index().then(({ data }) => { + setGraphqlUrl(data.graphqlWebsocketUrl); }).catch((error) => { loadingContextInfo.setLoading(false, ''); throw new Error('Error fetching GraphQL URL: '.concat(error.message || '')); }); logger.info('Fetching GraphQL URL'); - loadingContextInfo.setLoading(true, '1/4'); + loadingContextInfo.setLoading(true, '1/2'); }, []); + useEffect(() => { + const interval = setInterval(() => { + const tsNow = Date.now(); + + if (tsLastMessageRef.current !== 0 && tsLastPingMessageRef.current !== 0) { + if ((tsNow - tsLastMessageRef.current > boundary.current) && connectionStatus.getServerIsResponding()) { + connectionStatus.setServerIsResponding(false); + } else if ((tsNow - tsLastPingMessageRef.current > boundary.current) && connectionStatus.getPingIsComing()) { + connectionStatus.setPingIsComing(false); + } + + if (tsNow - tsLastMessageRef.current < boundary.current && !connectionStatus.getServerIsResponding()) { + connectionStatus.setServerIsResponding(true); + } else if (tsNow - tsLastPingMessageRef.current < boundary.current && !connectionStatus.getPingIsComing()) { + connectionStatus.setPingIsComing(true); + } + } + }, 5_000); + return () => clearInterval(interval); + }, []); + + useEffect(() => { + if (errorCounts === numberOfAttempts.current) { + throw new Error('Error connecting to server, retrying attempts exceeded'); + } + }, [errorCounts]); + + useEffect(() => { + if (terminalError) { + throw new Error(terminalError); + } + }, [terminalError]); + useEffect(() => { logger.info('Connecting to GraphQL server'); - loadingContextInfo.setLoading(true, '2/4'); + loadingContextInfo.setLoading(true, '2/2'); if (graphqlUrl) { const urlParams = new URLSearchParams(window.location.search); const sessionToken = urlParams.get('sessionToken'); @@ -80,26 +121,77 @@ const ConnectionManager: React.FC = ({ children }): Reac } sessionStorage.setItem('sessionToken', sessionToken); + const clientSessionUUID = sessionStorage.getItem('clientSessionUUID'); + const { isMobile } = deviceInfo; + let wsLink; try { - const subscription = new SubscriptionClient(graphqlUrl, { - reconnect: true, - timeout: 30000, - minTimeout: 30000, + const subscription = createClient({ + url: graphqlUrl, + retryAttempts: numberOfAttempts.current, + keepAlive: 99999999999, + retryWait: async () => { + return new Promise((res) => { + setTimeout(() => { + res(); + }, 10_000); + }); + }, + shouldRetry: (error) => { + logger.error('Connection error:', error); + if (error && typeof error === 'object' && 'code' in error && error.code === 4403) { + loadingContextInfo.setLoading(false, ''); + setTerminalError('Server refused the connection'); + return false; + } + + if (!apolloContextHolder.getShouldRetry()) return false; + return true; + }, connectionParams: { headers: { 'X-Session-Token': sessionToken, + 'X-ClientSessionUUID': clientSessionUUID, + 'X-ClientType': 'HTML5', + 'X-ClientIsMobile': isMobile ? 'true' : 'false', }, }, + on: { + error: (error) => { + logger.error('Error: on subscription to server', error); + loadingContextInfo.setLoading(false, ''); + connectionStatus.setConnectedStatus(false); + setErrorCounts((prev: number) => prev + 1); + }, + closed: (e) => { + // Check if it's a CloseEvent (which includes HTTP errors during WebSocket handshake) + if (e instanceof CloseEvent) { + logger.error(`WebSocket closed with code ${e.code}: ${e.reason}`); + loadingContextInfo.setLoading(false, ''); + setTerminalError('Server closed the connection'); + } + connectionStatus.setConnectedStatus(false); + }, + connected: (socket) => { + activeSocket.current = socket as WebSocket; + connectionStatus.setConnectedStatus(true); + }, + connecting: () => { + connectionStatus.setConnectedStatus(false); + }, + message: (message) => { + if (message.type === 'ping') { + tsLastPingMessageRef.current = Date.now(); + } + tsLastMessageRef.current = Date.now(); + }, + + }, }); - subscription.onError(() => { - loadingContextInfo.setLoading(false, ''); - throw new Error('Error: on subscription to server'); - }); - wsLink = new WebSocketLink( + const graphWsLink = new GraphQLWsLink( subscription, ); - wsLink = ApolloLink.from([payloadSizeCheckLink, wsLink]); + wsLink = ApolloLink.from([payloadSizeCheckLink, errorLink, graphWsLink]); wsLink.setOnError((error) => { loadingContextInfo.setLoading(false, ''); throw new Error('Error: on apollo connection'.concat(JSON.stringify(error) || '')); @@ -114,7 +206,7 @@ const ConnectionManager: React.FC = ({ children }): Reac client = new ApolloClient({ link: wsLink, cache: new InMemoryCache(), - connectToDevTools: true, + connectToDevTools: process.env.NODE_ENV === 'development', }); setApolloClient(client); apolloContextHolder.setClient(client); diff --git a/bigbluebutton-html5/imports/ui/components/connection-manager/startup-data-fetch/component.tsx b/bigbluebutton-html5/imports/ui/components/connection-manager/startup-data-fetch/component.tsx deleted file mode 100644 index 849c29feab..0000000000 --- a/bigbluebutton-html5/imports/ui/components/connection-manager/startup-data-fetch/component.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import React, { useEffect } from 'react'; -import { Session } from 'meteor/session'; -import { ErrorScreen } from '../../error-screen/component'; -import LoadingScreen from '../../common/loading-screen/component'; - -const connectionTimeout = 60000; - -interface Response { - meeting_clientSettings: Array<{ - askForFeedbackOnLogout: boolean, - allowDefaultLogoutUrl: boolean, - learningDashboardBase: string, - fallbackLocale: string, - fallbackOnEmptyString: boolean, - mediaTag: string, - clientLog: { - server: { - level: string, - enabled: boolean - }, - console: { - level: string, - enabled: true - }, - external: { - url: string, - level: string, - logTag: string, - method: string, - enabled: boolean, - flushOnClose: boolean, - throttleInterval: number, - } - } - }> -} - -interface StartupDataFetchProps { - children: React.ReactNode; -} - -const StartupDataFetch: React.FC = ({ - children, -}) => { - const [settingsFetched, setSettingsFetched] = React.useState(false); - const [error, setError] = React.useState(''); - const timeoutRef = React.useRef>(); - const [loading, setLoading] = React.useState(false); - useEffect(() => { - setLoading(true); - timeoutRef.current = setTimeout(() => { - setError('Timeout on fetching startup data'); - setLoading(false); - }, connectionTimeout); - const urlParams = new URLSearchParams(window.location.search); - const sessionToken = urlParams.get('sessionToken'); - - if (!sessionToken) { - setError('Missing session token'); - setLoading(false); - return; - } - const clientStartupSettings = `/api/rest/clientStartupSettings/?sessionToken=${sessionToken}`; - const url = new URL(`${window.location.origin}${clientStartupSettings}`); - fetch(url, { method: 'get' }) - .then((resp) => resp.json()) - .then((data: Response) => { - const settings = data.meeting_clientSettings[0]; - sessionStorage.setItem('clientStartupSettings', JSON.stringify(settings || {})); - setSettingsFetched(true); - clearTimeout(timeoutRef.current); - setLoading(false); - }).catch(() => { - Session.set('errorMessageDescription', 'meeting_ended'); - setError('Error fetching startup data'); - setLoading(false); - }); - }, []); - - return ( - <> - {settingsFetched ? children : null} - {error - ? ( - - ) - : null} - {loading - ? ( - -
- Loading... -
-
- ) - : null} - - ); -}; - -export default StartupDataFetch; diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/button/component.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/button/component.jsx index 22df2fe8ca..0ef82ec7cf 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/button/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/button/component.jsx @@ -40,16 +40,12 @@ class ConnectionStatusButton extends PureComponent { setModalIsOpen = (isOpen) => this.setState({ isModalOpen: isOpen }); renderModal(isModalOpen) { - const { isGridLayout, paginationEnabled, viewParticipantsWebcams } = this.props; return ( isModalOpen ? : null ) diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/button/container.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/button/container.jsx index 8d3c0a121a..ca0d4eda59 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/button/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/button/container.jsx @@ -1,33 +1,23 @@ import React from 'react'; -import { Meteor } from 'meteor/meteor'; -import { withTracker } from 'meteor/react-meteor-data'; -import { useSubscription } from '@apollo/client'; -import Settings from '/imports/ui/services/settings'; +import { useReactiveVar } from '@apollo/client'; import ConnectionStatusButtonComponent from './component'; -import { USER_CURRENT_STATUS_SUBSCRIPTION } from '../queries'; -import Auth from '/imports/ui/services/auth'; +import connectionStatus from '/imports/ui/core/graphql/singletons/connectionStatus'; +import { getWorstStatus } from '../service'; -const connectionStatusButtonContainer = (props) => { - const { data } = useSubscription(USER_CURRENT_STATUS_SUBSCRIPTION, { - variables: { userId: Auth.userID }, - }); - const myCurrentStatus = data && data.length > 0 - ? data[0].currentStatus - : 'normal'; +const ConnectionStatusButtonContainer = (props) => { + const connected = useReactiveVar(connectionStatus.getConnectedStatusVar()); + const rttStatus = useReactiveVar(connectionStatus.getRttStatusVar()); + const packetLossStatus = useReactiveVar(connectionStatus.getPacketLossStatusVar()); - return ; + const myCurrentStatus = getWorstStatus([rttStatus, packetLossStatus]); + + return ( + + ); }; -export default withTracker(() => { - const { connected } = Meteor.status(); - const isGridLayout = Session.get('isGridEnabled'); - const { paginationEnabled } = Settings.application; - const { viewParticipantsWebcams } = Settings.dataSaving; - - return { - connected, - isGridLayout, - paginationEnabled, - viewParticipantsWebcams, - }; -})(connectionStatusButtonContainer); +export default ConnectionStatusButtonContainer; diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/component.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/component.jsx index e27feec92e..7ffe151cfe 100755 --- a/bigbluebutton-html5/imports/ui/components/connection-status/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/component.jsx @@ -1,33 +1,78 @@ import { useEffect, useRef } from 'react'; import { useMutation } from '@apollo/client'; import { UPDATE_CONNECTION_ALIVE_AT } from './mutations'; +import { + getStatus, + handleAudioStatsEvent, + startMonitoringNetwork, +} from '/imports/ui/components/connection-status/service'; +import connectionStatus from '../../core/graphql/singletons/connectionStatus'; -const STATS_INTERVAL = window.meetingClientSettings.public.stats.interval; +import getBaseUrl from '/imports/ui/core/utils/getBaseUrl'; +import useCurrentUser from '../../core/hooks/useCurrentUser'; const ConnectionStatus = () => { + const STATS_INTERVAL = window.meetingClientSettings.public.stats.interval; const networkRttInMs = useRef(0); // Ref to store the last rtt const timeoutRef = useRef(null); const [updateConnectionAliveAtM] = useMutation(UPDATE_CONNECTION_ALIVE_AT); + const { + data, + } = useCurrentUser((u) => ({ + userId: u.userId, + avatar: u.avatar, + isModerator: u.isModerator, + color: u.color, + currentlyInMeeting: u.currentlyInMeeting, + })); + const handleUpdateConnectionAliveAt = () => { const startTime = performance.now(); - updateConnectionAliveAtM({ - variables: { - networkRttInMs: networkRttInMs.current, - }, - }).then(() => { - const endTime = performance.now(); - networkRttInMs.current = endTime - startTime; - }).finally(() => { - if (timeoutRef.current) { - clearTimeout(timeoutRef.current); - } + fetch( + `${getBaseUrl()}/ping`, + { signal: AbortSignal.timeout(STATS_INTERVAL) }, + ) + .then((res) => { + if (res.ok && res.status === 200) { + const rttLevels = window.meetingClientSettings.public.stats.rtt; + const endTime = performance.now(); + const networkRtt = Math.round(endTime - startTime); + networkRttInMs.current = networkRtt; + updateConnectionAliveAtM({ + variables: { + networkRttInMs: networkRtt, + }, + }); + const rttStatus = getStatus(rttLevels, networkRtt); + connectionStatus.setRttValue(networkRtt); + connectionStatus.setRttStatus(rttStatus); + connectionStatus.setLastRttRequestSuccess(true); - timeoutRef.current = setTimeout(() => { - handleUpdateConnectionAliveAt(); - }, STATS_INTERVAL); - }); + if (Object.keys(rttLevels).includes(rttStatus)) { + connectionStatus.addUserNetworkHistory( + data, + rttStatus, + Date.now(), + ); + } + } + }) + .catch(() => { + connectionStatus.setLastRttRequestSuccess(false); + // gets the worst status + connectionStatus.setRttStatus('critical'); + }) + .finally(() => { + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + + timeoutRef.current = setTimeout(() => { + handleUpdateConnectionAliveAt(); + }, STATS_INTERVAL); + }); }; useEffect(() => { @@ -36,6 +81,21 @@ const ConnectionStatus = () => { timeoutRef.current = setTimeout(() => { handleUpdateConnectionAliveAt(); }, STATS_INTERVAL / 2); + + const STATS_ENABLED = window.meetingClientSettings.public.stats.enabled; + + if (STATS_ENABLED) { + window.addEventListener('audiostats', handleAudioStatsEvent); + startMonitoringNetwork(); + } + + return () => { + window.removeEventListener('audiostats', handleAudioStatsEvent); + + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + }; }, []); return null; diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx index 3788029ce9..4569877903 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx @@ -2,13 +2,15 @@ import React, { PureComponent } from 'react'; import { FormattedTime, defineMessages, injectIntl } from 'react-intl'; import PropTypes from 'prop-types'; import UserAvatar from '/imports/ui/components/user-avatar/component'; +import CommonIcon from '/imports/ui/components/common/icon/component'; +import TooltipContainer from '/imports/ui/components/common/tooltip/container'; import Icon from '/imports/ui/components/connection-status/icon/component'; -import Service from '../service'; +import { getHelp } from '../service'; import Styled from './styles'; import ConnectionStatusHelper from '../status-helper/component'; import Auth from '/imports/ui/services/auth'; +import connectionStatus from '../../../core/graphql/singletons/connectionStatus'; -const NETWORK_MONITORING_INTERVAL_MS = 2000; const MIN_TIMEOUT = 3000; const intlMessages = defineMessages({ @@ -132,6 +134,10 @@ const intlMessages = defineMessages({ id: 'app.connection-status.clientNotRespondingWarning', description: 'Text for Client not responding warning', }, + noEvent: { + id: 'app.connection-status.connectionStatusNoEvent', + description: 'Text for inform on status without event ot time of occurrence', + }, }); const propTypes = { @@ -141,15 +147,15 @@ const propTypes = { }).isRequired, }; -const isConnectionStatusEmpty = (connectionStatus) => { +const isConnectionStatusEmpty = (connectionStatusParam) => { // Check if it's defined - if (!connectionStatus) return true; + if (!connectionStatusParam) return true; // Check if it's an array - if (!Array.isArray(connectionStatus)) return true; + if (!Array.isArray(connectionStatusParam)) return true; // Check if is empty - if (connectionStatus.length === 0) return true; + if (connectionStatusParam.length === 0) return true; return false; }; @@ -160,27 +166,11 @@ class ConnectionStatusComponent extends PureComponent { const { intl } = this.props; - this.help = Service.getHelp(); + this.help = getHelp(); this.state = { selectedTab: 0, - hasNetworkData: false, + hasNetworkData: true, copyButtonText: intl.formatMessage(intlMessages.copy), - networkData: { - user: { - - }, - audio: { - audioCurrentUploadRate: 0, - audioCurrentDownloadRate: 0, - jitter: 0, - packetsLost: 0, - transportStats: {}, - }, - video: { - videoCurrentUploadRate: 0, - videoCurrentDownloadRate: 0, - }, - }, }; this.setButtonMessage = this.setButtonMessage.bind(this); this.rateInterval = null; @@ -191,12 +181,12 @@ class ConnectionStatusComponent extends PureComponent { this.handleSelectTab = this.handleSelectTab.bind(this); } - async componentDidMount() { - this.startMonitoringNetwork(); - } + // async componentDidMount() { + // this.startMonitoringNetwork(); + // } componentWillUnmount() { - Meteor.clearInterval(this.rateInterval); + clearInterval(this.rateInterval); } handleSelectTab(tab) { @@ -211,66 +201,6 @@ class ConnectionStatusComponent extends PureComponent { }); } - /** - * Start monitoring the network data. - * @return {Promise} A Promise that resolves when process started. - */ - async startMonitoringNetwork() { - const { getVideoStreamsStats } = this.props; - let previousData = await Service.getNetworkData(getVideoStreamsStats); - this.rateInterval = Meteor.setInterval(async () => { - const data = await Service.getNetworkData(getVideoStreamsStats); - - const { - outbound: audioCurrentUploadRate, - inbound: audioCurrentDownloadRate, - } = Service.calculateBitsPerSecond(data.audio, previousData.audio); - - const inboundRtp = Service.getDataType(data.audio, 'inbound-rtp')[0]; - - const jitter = inboundRtp - ? inboundRtp.jitterBufferAverage - : 0; - - const packetsLost = inboundRtp - ? inboundRtp.packetsLost - : 0; - - const audio = { - audioCurrentUploadRate, - audioCurrentDownloadRate, - jitter, - packetsLost, - transportStats: data.audio.transportStats, - }; - - const { - outbound: videoCurrentUploadRate, - inbound: videoCurrentDownloadRate, - } = Service.calculateBitsPerSecondFromMultipleData(data.video, - previousData.video); - - const video = { - videoCurrentUploadRate, - videoCurrentDownloadRate, - }; - - const { user } = data; - - const networkData = { - user, - audio, - video, - }; - - previousData = data; - this.setState({ - networkData, - hasNetworkData: true, - }); - }, NETWORK_MONITORING_INTERVAL_MS); - } - /** * Copy network data to clipboard * @return {Promise} A Promise that is resolved after data is copied. @@ -278,9 +208,8 @@ class ConnectionStatusComponent extends PureComponent { * */ async copyNetworkData() { - const { intl } = this.props; + const { intl, networkData } = this.props; const { - networkData, hasNetworkData, } = this.state; @@ -321,11 +250,14 @@ class ConnectionStatusComponent extends PureComponent { const { selectedTab } = this.state; - if (isConnectionStatusEmpty(connectionData)) return this.renderEmpty(); + if (isConnectionStatusEmpty(connectionData) && selectedTab !== 1) return this.renderEmpty(); let connections = connectionData; if (selectedTab === 1) { connections = connections.filter((curr) => curr.user.userId === Auth.userID); + if (isConnectionStatusEmpty(connections)) { + connections = connectionStatus.getUserNetworkHistory(); + } if (isConnectionStatusEmpty(connections)) return this.renderEmpty(); } @@ -351,19 +283,25 @@ class ConnectionStatusComponent extends PureComponent { {conn.user.name} - {!conn.user.isOnline ? ` (${intl.formatMessage(intlMessages.offline)})` : null} + {!conn.user.currentlyInMeeting ? ` (${intl.formatMessage(intlMessages.offline)})` : null} - - - - - - {conn.clientNotResponding && conn.user.isOnline + { + !conn.clientNotResponding ? ( + + + + + + ) : null + } + {conn.clientNotResponding && conn.user.currentlyInMeeting ? ( {intl.formatMessage(intlMessages.clientNotResponding)} @@ -372,13 +310,22 @@ class ConnectionStatusComponent extends PureComponent { - {conn.lastUnstableStatusAt - ? ( - - ) - : null} + { + conn.lastUnstableStatusAt + ? ( + + ) + : ( + + + + ) + } @@ -407,7 +354,7 @@ class ConnectionStatusComponent extends PureComponent { const { intl, setModalIsOpen, connectionData } = this.props; - const { networkData } = this.state; + const { networkData } = this.props; const { audioCurrentUploadRate, @@ -511,7 +458,9 @@ class ConnectionStatusComponent extends PureComponent { disabled={!hasNetworkData} role="button" data-test="copyStats" + // eslint-disable-next-line react/jsx-no-bind onClick={this.copyNetworkData.bind(this)} + // eslint-disable-next-line react/jsx-no-bind onKeyPress={this.copyNetworkData.bind(this)} tabIndex={0} > @@ -564,8 +513,7 @@ class ConnectionStatusComponent extends PureComponent { {intl.formatMessage(intlMessages.sessionLogs)} - ) - } + )}
@@ -581,8 +529,7 @@ class ConnectionStatusComponent extends PureComponent {
    {this.renderConnections()}
- ) - } + )} diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/container.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/modal/container.jsx index a90f4be580..d6f0a08b28 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/container.jsx @@ -1,28 +1,26 @@ import React from 'react'; -import { useSubscription } from '@apollo/client'; import { CONNECTION_STATUS_REPORT_SUBSCRIPTION } from '../queries'; import Service from '../service'; import Component from './component'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; -import { useGetStats } from '../../video-provider/video-provider-graphql/hooks'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; +import { useReactiveVar } from '@apollo/client'; +import connectionStatus from '/imports/ui/core/graphql/singletons/connectionStatus'; const ConnectionStatusContainer = (props) => { - const { data } = useSubscription(CONNECTION_STATUS_REPORT_SUBSCRIPTION); + const { data } = useDeduplicatedSubscription(CONNECTION_STATUS_REPORT_SUBSCRIPTION); const connectionData = data ? Service.sortConnectionData(data.user_connectionStatusReport) : []; const { data: currentUser } = useCurrentUser((u) => ({ isModerator: u.isModerator })); const amIModerator = !!currentUser?.isModerator; - const { isGridLayout, paginationsEnabled, viewParticipantsWebcams } = props; - const getVideoStreamsStats = useGetStats( - isGridLayout, - paginationsEnabled, - viewParticipantsWebcams, - ); + + const newtworkData = useReactiveVar(connectionStatus.getNetworkDataVar()); + return ( ); }; diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js b/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js index b921df3d87..e5245196f4 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js +++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/styles.js @@ -17,7 +17,6 @@ import { titlePositionLeft, mdPaddingX, borderSizeLarge, - jumboPaddingY, } from '/imports/ui/stylesheets/styled-components/general'; import { fontSizeSmall, @@ -82,7 +81,6 @@ const ClientNotRespondingText = styled.div` } `; - const Text = styled.div` padding-left: .5rem; white-space: nowrap; @@ -165,7 +163,7 @@ const CopyContainer = styled.div` justify-content: flex-end; border: none; border-top: 1px solid ${colorOffWhite}; - padding: ${jumboPaddingY} 0 0; + padding: ${mdPaddingX} 0 0 0; `; const ConnectionStatusModal = styled(ModalSimple)` diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/queries.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/queries.jsx index 76ac0b1361..1f15e6bdde 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/queries.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/queries.jsx @@ -14,7 +14,7 @@ export const CONNECTION_STATUS_REPORT_SUBSCRIPTION = gql`subscription ConnStatus avatar color isModerator - isOnline + currentlyInMeeting } clientNotResponding lastUnstableStatus diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/service.js b/bigbluebutton-html5/imports/ui/components/connection-status/service.js index 83733abd01..de44c56cf8 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/service.js +++ b/bigbluebutton-html5/imports/ui/components/connection-status/service.js @@ -1,13 +1,12 @@ import { defineMessages } from 'react-intl'; +import { makeVar } from '@apollo/client'; import Auth from '/imports/ui/services/auth'; -import { Session } from 'meteor/session'; +import Session from '/imports/ui/services/storage/in-memory'; import { notify } from '/imports/ui/services/notification'; import AudioService from '/imports/ui/components/audio/service'; -import VideoService from '/imports/ui/components/video-provider/video-provider-graphql/service'; import ScreenshareService from '/imports/ui/components/screenshare/service'; - -const STATS = window.meetingClientSettings.public.stats; -const NOTIFICATION = STATS.notification; +import VideoService from '/imports/ui/components/video-provider/service'; +import connectionStatus from '../../core/graphql/singletons/connectionStatus'; const intlMessages = defineMessages({ saved: { @@ -20,85 +19,96 @@ const intlMessages = defineMessages({ }, }); -let lastLevel = -1; -const levelDep = new Tracker.Dependency(); +export const NETWORK_MONITORING_INTERVAL_MS = 2000; + +export const lastLevel = makeVar(); let statsTimeout = null; -const URL_REGEX = new RegExp(/^(http|https):\/\/[^ "]+$/); -const getHelp = () => { +export const URL_REGEX = new RegExp(/^(http|https):\/\/[^ "]+$/); +export const getHelp = () => { + const STATS = window.meetingClientSettings.public.stats; + if (URL_REGEX.test(STATS.help)) return STATS.help; return null; }; -const getStats = () => { - levelDep.depend(); - return STATS.level[lastLevel]; -}; +export function getStatus(levels, value) { + const sortedLevels = Object.entries(levels) + .map((entry) => [entry[0], Number(entry[1])]) + .sort((a, b) => a[1] - b[1]); -const setStats = (level = -1, type = 'recovery', value = {}) => { - if (lastLevel !== level) { - lastLevel = level; - levelDep.changed(); - } -}; - -const handleAudioStatsEvent = (event) => { - const { detail } = event; - if (detail) { - const { loss, jitter } = detail; - let active = false; - // From higher to lower - for (let i = STATS.level.length - 1; i >= 0; i--) { - if (loss >= STATS.loss[i] || jitter >= STATS.jitter[i]) { - active = true; - setStats(i, 'audio', { loss, jitter }); - break; - } + for (let i = 0; i < sortedLevels.length; i += 1) { + if (value < sortedLevels[i][1]) { + return i === 0 ? 'normal' : sortedLevels[i - 1][0]; + } + if (i === sortedLevels.length - 1) { + return sortedLevels[i][0]; } - - if (active) startStatsTimeout(); } -}; -const startStatsTimeout = () => { - if (statsTimeout !== null) clearTimeout(statsTimeout); - - statsTimeout = setTimeout(() => { - setStats(-1, 'recovery', {}); - }, STATS.timeout); -}; - -const sortLevel = (a, b) => { - const indexOfA = STATS.level.indexOf(a.level); - const indexOfB = STATS.level.indexOf(b.level); - - if (indexOfA < indexOfB) return 1; - if (indexOfA === indexOfB) return 0; - if (indexOfA > indexOfB) return -1; -}; - -const sortOnline = (a, b) => { - if (!a.user.isOnline && b.user.isOnline) return 1; - if (a.user.isOnline === b.user.isOnline) return 0; - if (a.user.isOnline && !b.user.isOnline) return -1; -}; - -const isEnabled = () => STATS.enabled; - -if (STATS.enabled) { - window.addEventListener('audiostats', handleAudioStatsEvent); + return sortedLevels[sortedLevels.length - 1][0]; } -const getNotified = () => { - const notified = Session.get('connectionStatusNotified'); +export const getStats = () => { + const STATS = window.meetingClientSettings.public.stats; + return STATS.level[lastLevel()]; +}; + +export const handleAudioStatsEvent = (event) => { + const { detail } = event; + + if (detail) { + const { loss } = detail; + + // The stat provided by this event is the *INBOUND* packet loss fraction + // calculated manually by using the packetsLost and packetsReceived metrics. + // It uses a 5 probe wide window - so roughly a 10 seconds period with a 2 + // seconds interval between captures. + // + // This metric is DIFFERENT from the one used in the connection status modal + // (see the network data object in this file). The network data one is an + // absolute counter of INBOUND packets lost - and it *SHOULD NOT* be used to + // determine alert triggers + connectionStatus.setPacketLossStatus( + getStatus(window.meetingClientSettings.public.stats.loss, loss), + ); + } +}; + +export const sortLevel = (a, b) => { + const RTT = window.meetingClientSettings.public.stats.rtt; + + if (!a.lastUnstableStatus && !b.lastUnstableStatus) return 0; + if (!a.lastUnstableStatus) return 1; + if (!b.lastUnstableStatus) return -1; + + const rttOfA = RTT[a.lastUnstableStatus]; + const rttOfB = RTT[b.lastUnstableStatus]; + + return rttOfB - rttOfA; +}; + +export const sortOnline = (a, b) => { + if (!a.user.currentlyInMeeting && b.user.currentlyInMeeting) return 1; + if (a.user.currentlyInMeeting === b.user.currentlyInMeeting) return 0; + if (a.user.currentlyInMeeting && !b.user.currentlyInMeeting) return -1; + return 0; +}; + +export const isEnabled = () => window.meetingClientSettings.public.stats.enabled; + +export const getNotified = () => { + const notified = Session.getItem('connectionStatusNotified'); // Since notified can be undefined we need a boolean verification return notified === true; }; -const notification = (level, intl) => { +export const notification = (level, intl) => { + const NOTIFICATION = window.meetingClientSettings.public.stats.notification; + if (!NOTIFICATION[level]) return null; // Avoid toast spamming @@ -106,9 +116,10 @@ const notification = (level, intl) => { if (notified) { return null; } - Session.set('connectionStatusNotified', true); + Session.setItem('connectionStatusNotified', true); if (intl) notify(intl.formatMessage(intlMessages.notification), level, 'warning'); + return null; }; /** @@ -119,7 +130,7 @@ const notification = (level, intl) => { * in getStats() call. * @returns The jitter buffer average in ms */ -const calculateJitterBufferAverage = (inboundRtpData) => { +export const calculateJitterBufferAverage = (inboundRtpData) => { if (!inboundRtpData) return 0; const { @@ -158,7 +169,7 @@ const getDataType = (data, type) => { * @returns {Object} the currentData object with the extra inbound network * added to it. */ -const addExtraInboundNetworkParameters = (data) => { +export const addExtraInboundNetworkParameters = (data) => { if (!data) return data; const inboundRtpData = getDataType(data, 'inbound-rtp')[0]; @@ -186,7 +197,7 @@ const addExtraInboundNetworkParameters = (data) => { * and * https://www.w3.org/TR/webrtc-stats/#dom-rtcoutboundrtpstreamstats */ -const getAudioData = async () => { +export const getAudioData = async () => { const data = await AudioService.getStats(); if (!data) return {}; @@ -204,8 +215,8 @@ const getAudioData = async () => { * @returns An Object containing video data for all video peers and screenshare * peer */ -const getVideoData = async (getVideoStreamsStats) => { - const camerasData = await getVideoStreamsStats() || {}; +export const getVideoData = async () => { + const camerasData = await VideoService.getStats() || {}; const screenshareData = await ScreenshareService.getStats() || {}; @@ -220,10 +231,10 @@ const getVideoData = async (getVideoStreamsStats) => { * For audio, this will get information about the mic/listen-only stream. * @returns An Object containing all this data. */ -const getNetworkData = async (getVideoStreamsStats) => { +export const getNetworkData = async () => { const audio = await getAudioData(); - const video = await getVideoData(getVideoStreamsStats); + const video = await getVideoData(); const user = { time: new Date(), @@ -261,7 +272,7 @@ const getNetworkData = async (getVideoStreamsStats) => { * @returns An object of numbers, containing both outbound (upload) and inbound * (download) rates (kbps). */ -const calculateBitsPerSecond = (currentData, previousData) => { +export const calculateBitsPerSecond = (currentData, previousData) => { const result = { outbound: 0, inbound: 0, @@ -349,7 +360,7 @@ const calculateBitsPerSecond = (currentData, previousData) => { * representing a data collected in past * (previous call of service's getNetworkData()) */ -const calculateBitsPerSecondFromMultipleData = (currentData, previousData) => { +export const calculateBitsPerSecondFromMultipleData = (currentData, previousData) => { const result = { outbound: 0, inbound: 0, @@ -374,6 +385,83 @@ const calculateBitsPerSecondFromMultipleData = (currentData, previousData) => { const sortConnectionData = (connectionData) => connectionData.sort(sortLevel).sort(sortOnline); +/** + * Start monitoring the network data. + * @return {Promise} A Promise that resolves when process started. + */ +export async function startMonitoringNetwork() { + let previousData = await getNetworkData(); + + setInterval(async () => { + const data = await getNetworkData(); + + const { + outbound: audioCurrentUploadRate, + inbound: audioCurrentDownloadRate, + } = calculateBitsPerSecond(data.audio, previousData.audio); + + const inboundRtp = getDataType(data.audio, 'inbound-rtp')[0]; + + const jitter = inboundRtp + ? inboundRtp.jitterBufferAverage + : 0; + + const packetsLost = inboundRtp + ? inboundRtp.packetsLost + : 0; + + const audio = { + audioCurrentUploadRate, + audioCurrentDownloadRate, + jitter, + packetsLost, + transportStats: data.audio.transportStats, + }; + + const { + outbound: videoCurrentUploadRate, + inbound: videoCurrentDownloadRate, + } = calculateBitsPerSecondFromMultipleData(data.video, + previousData.video); + + const video = { + videoCurrentUploadRate, + videoCurrentDownloadRate, + }; + + const { user } = data; + + const networkData = { + user, + audio, + video, + }; + + previousData = data; + + connectionStatus.setNetworkData(networkData); + }, NETWORK_MONITORING_INTERVAL_MS); +} + +export function getWorstStatus(statuses) { + const statusOrder = { + normal: 0, + warning: 1, + danger: 2, + critical: 3, + }; + + let worstStatus = 'normal'; + // eslint-disable-next-line + for (let status of statuses) { + if (statusOrder[status] > statusOrder[worstStatus]) { + worstStatus = status; + } + } + + return worstStatus; +} + export default { getStats, getHelp, @@ -384,4 +472,7 @@ export default { calculateBitsPerSecondFromMultipleData, getDataType, sortConnectionData, + startMonitoringNetwork, + getStatus, + getWorstStatus, }; diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/status-helper/component.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/status-helper/component.jsx index 5280588a06..f907401c52 100644 --- a/bigbluebutton-html5/imports/ui/components/connection-status/status-helper/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/connection-status/status-helper/component.jsx @@ -1,9 +1,11 @@ import React, { Fragment, PureComponent } from 'react'; import { defineMessages, injectIntl } from 'react-intl'; +import { useReactiveVar } from '@apollo/client'; import Styled from './styles'; import Icon from '/imports/ui/components/connection-status/icon/component'; import SettingsMenuContainer from '/imports/ui/components/settings/container'; -import Auth from '/imports/ui/services/auth'; +import connectionStatus from '/imports/ui/core/graphql/singletons/connectionStatus'; +import { getWorstStatus } from '../service'; const intlMessages = defineMessages({ label: { @@ -24,9 +26,9 @@ class ConnectionStatusIcon extends PureComponent { this.setSettingsMenuModalIsOpen = this.setSettingsMenuModalIsOpen.bind(this); } - + // eslint-disable-next-line renderIcon(level = 'normal') { - return( + return ( curr.user.userId === Auth.userID); - - const currentStatus = ownConnectionData && ownConnectionData.length > 0 - ? ownConnectionData[0].currentStatus - : 'normal'; - let color; switch (currentStatus) { case 'warning': @@ -79,7 +75,7 @@ class ConnectionStatusIcon extends PureComponent { const { isSettingsMenuModalOpen } = this.state; return ( - + <> {this.renderIcon(currentStatus)} @@ -90,29 +86,44 @@ class ConnectionStatusIcon extends PureComponent { ? (
{intl.formatMessage(intlMessages.settings)} - {isSettingsMenuModalOpen ? this.setSettingsMenuModalIsOpen(false), - priority: "medium", - setIsOpen: this.setSettingsMenuModalIsOpen, - isOpen: isSettingsMenuModalOpen, - }} - /> : null} + {isSettingsMenuModalOpen + ? ( + this.setSettingsMenuModalIsOpen(false), + priority: 'medium', + setIsOpen: this.setSettingsMenuModalIsOpen, + isOpen: isSettingsMenuModalOpen, + }} + /> + ) : null}
) : (
 
- ) - } -
+ )} + ); } } -export default injectIntl(ConnectionStatusIcon); +const WrapConnectionStatus = (props) => { + const rttStatus = useReactiveVar(connectionStatus.getRttStatusVar()); + const packetLossStatus = useReactiveVar(connectionStatus.getPacketLossStatusVar()); + const status = getWorstStatus([rttStatus, packetLossStatus]); + return ( + + ); +}; + +export default injectIntl(WrapConnectionStatus); diff --git a/bigbluebutton-html5/imports/ui/components/debug-window/component.jsx b/bigbluebutton-html5/imports/ui/components/debug-window/component.jsx index bc3cdc905b..389298666b 100644 --- a/bigbluebutton-html5/imports/ui/components/debug-window/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/debug-window/component.jsx @@ -43,9 +43,6 @@ const intlMessages = defineMessages({ }, }); -const DEBUG_WINDOW_ENABLED = window.meetingClientSettings.public.app.enableDebugWindow; -const SHOW_DEBUG_WINDOW_ACCESSKEY = window.meetingClientSettings.public.app.shortcuts.openDebugWindow.accesskey; - class DebugWindow extends Component { constructor(props) { super(props); @@ -57,6 +54,9 @@ class DebugWindow extends Component { } componentDidMount() { + const DEBUG_WINDOW_ENABLED = window.meetingClientSettings.public.app.enableDebugWindow; + const SHOW_DEBUG_WINDOW_ACCESSKEY = window.meetingClientSettings.public.app.shortcuts.openDebugWindow.accesskey; + document.addEventListener('keyup', (event) => { const { key, code } = event; const eventKey = key?.toUpperCase(); @@ -95,6 +95,8 @@ class DebugWindow extends Component { const { showDebugWindow, logLevel } = this.state; const chatLoggerLevelsNames = Object.keys(ChatLogger.levels); + const DEBUG_WINDOW_ENABLED = window.meetingClientSettings.public.app.enableDebugWindow; + if (!DEBUG_WINDOW_ENABLED || !showDebugWindow) return false; const { intl } = this.props; diff --git a/bigbluebutton-html5/imports/ui/components/dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/dropdown/component.jsx index 3c4ffa9341..4245583dbb 100644 --- a/bigbluebutton-html5/imports/ui/components/dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/dropdown/component.jsx @@ -5,7 +5,7 @@ import TetherComponent from 'react-tether'; import { defineMessages, injectIntl } from 'react-intl'; import deviceInfo from '/imports/utils/deviceInfo'; import screenreaderTrap from 'makeup-screenreader-trap'; -import { Session } from 'meteor/session'; +import Session from '/imports/ui/services/storage/in-memory'; import Styled from './styles'; import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component'; @@ -91,11 +91,14 @@ class Dropdown extends Component { this.handleHide = this.handleHide.bind(this); this.handleToggle = this.handleToggle.bind(this); this.handleWindowClick = this.handleWindowClick.bind(this); + this.handleContextMenu = this.handleContextMenu.bind(this); this.updateOrientation = this.updateOrientation.bind(this); + this.updateZIndex = this.updateZIndex.bind(this); } componentDidMount() { window.addEventListener('resize', this.updateOrientation); + window.addEventListener('contextmenu', this.handleContextMenu); } componentDidUpdate(prevProps, prevState) { @@ -125,20 +128,17 @@ class Dropdown extends Component { componentWillUnmount() { window.removeEventListener('resize', this.updateOrientation); + window.removeEventListener('contextmenu', this.handleContextMenu); } - handleHide() { - Session.set('dropdownOpen', false); - const { onHide } = this.props; - this.setState({ isOpen: false }, () => { - const { removeEventListener } = window; - onHide(); - removeEventListener('click', this.handleWindowClick, true); - }); + handleContextMenu(event) { + event.preventDefault(); + this.handleHide(); } handleShow() { - Session.set('dropdownOpen', true); + Session.setItem('dropdownOpen', true); + this.updateZIndex(0); const { onShow, } = this.props; @@ -149,6 +149,17 @@ class Dropdown extends Component { }); } + handleHide() { + Session.setItem('dropdownOpen', false); + this.updateZIndex(1); + const { onHide } = this.props; + this.setState({ isOpen: false }, () => { + const { removeEventListener } = window; + onHide(); + removeEventListener('click', this.handleWindowClick, true); + }); + } + handleWindowClick(event) { const { keepOpen, onHide } = this.props; const { isOpen } = this.state; @@ -194,6 +205,15 @@ class Dropdown extends Component { this.setState({ isPortrait: deviceInfo.isPortrait() }); } + updateZIndex(zIndex) { + if (this) { + const presentationInnerWrapper = document.getElementById('presentationInnerWrapper'); + if (presentationInnerWrapper) { + presentationInnerWrapper.style.zIndex = zIndex; + } + } + } + render() { const { children, diff --git a/bigbluebutton-html5/imports/ui/components/dropdown/list/separator/component.jsx b/bigbluebutton-html5/imports/ui/components/dropdown/list/separator/component.jsx index 31957b03fa..a5c98255dd 100644 --- a/bigbluebutton-html5/imports/ui/components/dropdown/list/separator/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/dropdown/list/separator/component.jsx @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import Styled from './styles'; -const DropdownListSeparator = ({ style }) => ( +const DropdownListSeparator = ({ style = null }) => ( ); @@ -10,8 +10,4 @@ DropdownListSeparator.propTypes = { style: PropTypes.shape({}), }; -DropdownListSeparator.defaultProps = { - style: null, -}; - export default DropdownListSeparator; diff --git a/bigbluebutton-html5/imports/ui/components/emoji-picker/component.jsx b/bigbluebutton-html5/imports/ui/components/emoji-picker/component.jsx index 9701597307..44a74e6007 100644 --- a/bigbluebutton-html5/imports/ui/components/emoji-picker/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/emoji-picker/component.jsx @@ -1,11 +1,9 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import { injectIntl } from 'react-intl'; import data from '@emoji-mart/data'; import Picker from '@emoji-mart/react'; -const DISABLE_EMOJIS = window.meetingClientSettings.public.chat.disableEmojis; - const propTypes = { intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, @@ -13,10 +11,6 @@ const propTypes = { onEmojiSelect: PropTypes.func.isRequired, }; -const emojisToExclude = [ - ...DISABLE_EMOJIS, -]; - const EmojiPicker = (props) => { const { intl, @@ -51,6 +45,19 @@ const EmojiPicker = (props) => { }, }; + const DISABLE_EMOJIS = window.meetingClientSettings.public.chat.disableEmojis; + + const emojisToExclude = [ + ...DISABLE_EMOJIS, + ]; + + // HACK: the library sets the width after it renders + // this code fixes that, but is kinda ugly and only works if + // we never render more than one emoji-picker at the same time + useEffect(() => { + document.getElementsByTagName('em-emoji-picker')[0].style.width = 'auto'; + }); + return ( { + const Settings = getSettingsSingletonInstance(); const containerRef = useRef(null); const [isAnimating, setIsAnimating] = useState(false); const EMOJI_SIZE = window.meetingClientSettings.public.app.emojiRain.emojiSize; @@ -23,7 +24,7 @@ const EmojiRain = ({ reactions }) => { return; } - for (i = 0; i < NUMBER_OF_EMOJIS; i++) { + for (let i = 0; i < NUMBER_OF_EMOJIS; i++) { const initialPosition = { x: coord.x + coord.width / 8, y: coord.y + coord.height / 5, diff --git a/bigbluebutton-html5/imports/ui/components/emoji-rain/container.jsx b/bigbluebutton-html5/imports/ui/components/emoji-rain/container.jsx index 040df7f0fd..65606dcdc8 100644 --- a/bigbluebutton-html5/imports/ui/components/emoji-rain/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/emoji-rain/container.jsx @@ -1,14 +1,14 @@ import React, { useRef } from 'react'; -import { useSubscription } from '@apollo/client'; import EmojiRain from './component'; import { getEmojisToRain } from './queries'; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; const EmojiRainContainer = () => { const nowDate = useRef(new Date().toUTCString()); const { data: emojisToRainData, - } = useSubscription(getEmojisToRain, { + } = useDeduplicatedSubscription(getEmojisToRain, { variables: { initialCursor: nowDate.current, }, diff --git a/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/component.jsx b/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/component.jsx index dd1ebb0e38..6635b33a77 100644 --- a/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/component.jsx @@ -26,8 +26,6 @@ const intlMessages = defineMessages({ }, }); -const { warnAboutUnsavedContentOnMeetingEnd } = window.meetingClientSettings.public.app; - const propTypes = { intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, @@ -50,6 +48,8 @@ class EndMeetingComponent extends PureComponent { ? intl.formatMessage(intlMessages.endMeetingDescription, { 0: users - 1 }) : intl.formatMessage(intlMessages.endMeetingNoUserDescription); + const { warnAboutUnsavedContentOnMeetingEnd } = window.meetingClientSettings.public.app; + if (warnAboutUnsavedContentOnMeetingEnd) { // the double breakline it to put one empty line between the descriptions description += `\n\n${intl.formatMessage(intlMessages.contentWarning)}`; diff --git a/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/container.jsx b/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/container.jsx index eb6cc600b2..79cb7f773d 100644 --- a/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/container.jsx @@ -1,17 +1,17 @@ import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; -import { useMutation, useSubscription } from '@apollo/client'; +import { useMutation } from '@apollo/client'; import EndMeetingComponent from './component'; -import Service from './service'; import logger from '/imports/startup/client/logger'; import { MEETING_END } from './mutations'; import { USER_AGGREGATE_COUNT_SUBSCRIPTION } from '/imports/ui/core/graphql/queries/users'; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; +import useMeeting from '../../core/hooks/useMeeting'; const EndMeetingContainer = (props) => { const [meetingEnd] = useMutation(MEETING_END); const { data: countData, - } = useSubscription(USER_AGGREGATE_COUNT_SUBSCRIPTION); + } = useDeduplicatedSubscription(USER_AGGREGATE_COUNT_SUBSCRIPTION); const users = countData?.user_aggregate?.aggregate?.count || 0; const { setIsOpen } = props; @@ -25,9 +25,18 @@ const EndMeetingContainer = (props) => { setIsOpen(false); }; - return ; + const { data: meeting } = useMeeting((m) => ({ + name: m.name, + })); + + return ( + + ); }; -export default withTracker(() => ({ - meetingTitle: Service.getMeetingTitle(), -}))(EndMeetingContainer); +export default EndMeetingContainer; diff --git a/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/service.js b/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/service.js deleted file mode 100644 index 5d2ecda243..0000000000 --- a/bigbluebutton-html5/imports/ui/components/end-meeting-confirmation/service.js +++ /dev/null @@ -1,14 +0,0 @@ -import Auth from '/imports/ui/services/auth'; -import Meetings from '/imports/api/meetings'; - -const getMeetingTitle = () => { - const meeting = Meetings.findOne({ - meetingId: Auth.meetingID, - }, { fields: { name: 1, 'breakoutPolicies.sequence': 1 } }); - - return meeting.name; -}; - -export default { - getMeetingTitle, -}; diff --git a/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx b/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx index 0762fb1e30..540103b9ad 100644 --- a/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/error-screen/component.jsx @@ -1,8 +1,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; -import { Meteor } from 'meteor/meteor'; -import { Session } from 'meteor/session'; +import Session from '/imports/ui/services/storage/in-memory'; import Styled from './styles'; const intlMessages = defineMessages({ @@ -94,13 +93,8 @@ class ErrorScreen extends PureComponent { componentDidMount() { const { code, callback, endedReason } = this.props; // stop audio - document.querySelector('audio').pause(); - navigator - .mediaDevices - .getUserMedia({ audio: true, video: true }) - .then((m) => m.getTracks().forEach((t) => t.stop())); window.dispatchEvent(new Event('StopAudioTracks')); - callback(endedReason, () => Meteor.disconnect()); + callback(endedReason, () => {}); console.error({ logCode: 'startup_client_usercouldnotlogin_error' }, `User could not log in HTML5, hit ${code}`); } @@ -113,7 +107,7 @@ class ErrorScreen extends PureComponent { errorInfo, } = this.props; let formatedMessage = 'Oops, something went wrong'; - let errorMessageDescription = Session.get('errorMessageDescription'); + let errorMessageDescription = Session.getItem('errorMessageDescription'); if (intl) { formatedMessage = intl.formatMessage(intlMessages[defaultProps.code]); @@ -121,7 +115,7 @@ class ErrorScreen extends PureComponent { formatedMessage = intl.formatMessage(intlMessages[code]); } - errorMessageDescription = Session.get('errorMessageDescription'); + errorMessageDescription = Session.getItem('errorMessageDescription'); if (errorMessageDescription in intlMessages) { errorMessageDescription = intl.formatMessage(intlMessages[errorMessageDescription]); diff --git a/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/component.tsx b/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/component.tsx index 6ba94e8c5e..2aaea07b8d 100644 --- a/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/component.tsx @@ -33,11 +33,14 @@ import ExternalVideoPlayerToolbar from './toolbar/component'; import deviceInfo from '/imports/utils/deviceInfo'; import { ACTIONS, PRESENTATION_AREA } from '../../layout/enums'; import { EXTERNAL_VIDEO_UPDATE } from '../mutations'; +import { calculateCurrentTime } from '/imports/ui/components/external-video-player/service'; import PeerTube from '../custom-players/peertube'; import { ArcPlayer } from '../custom-players/arc-player'; +import getStorageSingletonInstance from '/imports/ui/services/storage'; const AUTO_PLAY_BLOCK_DETECTION_TIMEOUT_SECONDS = 5; +const UPDATE_INTERVAL_THRESHOLD_MS = 500; const intlMessages = defineMessages({ autoPlayWarning: { @@ -70,10 +73,15 @@ interface ExternalVideoPlayerProps { externalVideo: ExternalVideo; playing: boolean; playerPlaybackRate: number; - currentTime: number; key: string; isSidebarContentOpen: boolean; setKey: (key: string) => void; + sendMessage: (event: string, data: { + rate: number; + time: number; + state?: string; + }) => void; + getCurrentTime(): number; } // @ts-ignore - PeerTubePlayer is not typed @@ -81,6 +89,8 @@ Styled.VideoPlayer.addCustomPlayer(PeerTube); // @ts-ignore - ArcPlayer is not typed Styled.VideoPlayer.addCustomPlayer(ArcPlayer); +const truncateTime = (time: number) => (time < 1 ? 0 : time); + const ExternalVideoPlayer: React.FC = ({ isGridLayout, isSidebarContentOpen, @@ -93,13 +103,14 @@ const ExternalVideoPlayer: React.FC = ({ isPresenter, playing, playerPlaybackRate, - currentTime, isEchoTest, key, setKey, + sendMessage, + getCurrentTime, }) => { const intl = useIntl(); - + const storage = getStorageSingletonInstance(); const { height, width, @@ -148,6 +159,9 @@ const ExternalVideoPlayer: React.FC = ({ controls: isPresenter ? 1 : 0, cc_lang_pref: document.getElementsByTagName('html')[0].lang.substring(0, 2), }, + embedOptions: { + host: 'https://www.youtube-nocookie.com', + }, }, peertube: { isPresenter, @@ -175,54 +189,28 @@ const ExternalVideoPlayer: React.FC = ({ const timeoutRef = useRef>(); const presenterRef = useRef(isPresenter); const [duration, setDuration] = React.useState(0); - const [reactPlayerState, setReactPlayerState] = React.useState(false); + const [reactPlayerPlaying, setReactPlayerPlaying] = React.useState(false); - const [updateExternalVideo] = useMutation(EXTERNAL_VIDEO_UPDATE); + let currentTime = getCurrentTime(); - let lastMessage: { - event: string; - rate: number; - time: number; - state?: string; - } = { event: '', rate: 0, time: 0 }; + const changeVolume = (newVolume: number) => { + setVolume(newVolume); + storage.setItem('externalVideoVolume', newVolume); + }; const handleDuration = (duration: number) => { setDuration(duration); }; - const sendMessage = (event: string, data: { rate: number; time: number; state?: string}) => { - // don't re-send repeated update messages - if ( - lastMessage.event === event - && lastMessage.time === data.time - ) { - return; + useEffect(() => { + const storedVolume = storage.getItem('externalVideoVolume'); + if (storedVolume) { + setVolume(storedVolume as number); } - - // don't register to redis a viewer joined message - if (event === 'viewerJoined') { - return; - } - - lastMessage = { ...data, event }; - - // Use an integer for playing state - // 0: stopped 1: playing - // We might use more states in the future - const state = data.state ? 1 : 0; - - updateExternalVideo({ - variables: { - status: event, - rate: data?.rate, - time: data?.time, - state, - }, - }); - }; + }, []); useEffect(() => { - const unsynchedPlayer = reactPlayerState !== playing; + const unsynchedPlayer = reactPlayerPlaying !== playing; if (unsynchedPlayer && !!videoUrl) { timeoutRef.current = setTimeout(() => { setShowUnsynchedMsg(true); @@ -231,12 +219,12 @@ const ExternalVideoPlayer: React.FC = ({ setShowUnsynchedMsg(false); clearTimeout(timeoutRef.current); } - }, [reactPlayerState, playing]); + }, [reactPlayerPlaying, playing]); useEffect(() => { const handleExternalVideoVolumeSet = (( event: CustomEvent, - ) => setVolume(event.detail.volume)) as EventListener; + ) => changeVolume(event.detail.volume)) as EventListener; window.addEventListener(ExternalVideoVolumeCommandsEnum.SET, handleExternalVideoVolumeSet); return () => { window.addEventListener(ExternalVideoVolumeCommandsEnum.SET, handleExternalVideoVolumeSet); @@ -244,8 +232,8 @@ const ExternalVideoPlayer: React.FC = ({ }, []); useEffect(() => { - if (playerRef.current) { - playerRef.current.seekTo(currentTime, 'seconds'); + if (playerRef.current && !isPresenter) { + playerRef.current.seekTo(truncateTime(currentTime), 'seconds'); } }, [playerRef.current, playing]); @@ -280,23 +268,33 @@ const ExternalVideoPlayer: React.FC = ({ } }, [isPresenter]); + const handleOnStart = () => { + if (!isPresenter) { + currentTime = getCurrentTime(); + playerRef.current?.seekTo(truncateTime(currentTime), 'seconds'); + } + }; + const handleOnPlay = () => { - setReactPlayerState(true); - if (isPresenter) { + setReactPlayerPlaying(true); + if (isPresenter && !playing) { const rate = playerRef.current?.getInternalPlayer()?.getPlaybackRate() as number ?? 1; + const currentTime = played * duration; sendMessage('play', { rate, time: currentTime, }); - } else if (!playing && !isPresenter) { + } + + if (!playing && !isPresenter) { playerRef.current?.getInternalPlayer().pauseVideo(); } }; const handleOnStop = () => { - setReactPlayerState(false); - if (isPresenter) { + setReactPlayerPlaying(false); + if (isPresenter && playing) { const rate = playerRef.current?.getInternalPlayer()?.getPlaybackRate() as number ?? 1; const currentTime = playerRef.current?.getCurrentTime() ?? 0; sendMessage('stop', { @@ -310,6 +308,19 @@ const ExternalVideoPlayer: React.FC = ({ } }; + const handleOnReady = (reactPlayer: ReactPlayer) => { + reactPlayer.seekTo(truncateTime(currentTime), 'seconds'); + }; + + const handleProgress = (state: OnProgressProps) => { + setPlayed(state.played); + setLoaded(state.loaded); + + if (playing && isPresenter) { + currentTime = playerRef.current?.getCurrentTime() || 0; + } + }; + const isMinimized = width === 0 && height === 0; // @ts-ignore accessing lib private property @@ -327,7 +338,7 @@ const ExternalVideoPlayer: React.FC = ({ } const shouldShowTools = () => { - if (isPresenter || (!isPresenter && isGridLayout && !isSidebarContentOpen)) { + if (isPresenter || (!isPresenter && isGridLayout && !isSidebarContentOpen) || !videoUrl) { return false; } return true; @@ -341,6 +352,7 @@ const ExternalVideoPlayer: React.FC = ({ top, left, right, + zIndex: externalVideo.zIndex, }} isResizing={isResizing} isMinimized={isMinimized} @@ -372,12 +384,11 @@ const ExternalVideoPlayer: React.FC = ({ width="100%" ref={playerRef} volume={volume} + onReady={handleOnReady} + onStart={handleOnStart} onPlay={handleOnPlay} onDuration={handleDuration} - onProgress={(state: OnProgressProps) => { - setPlayed(state.played); - setLoaded(state.loaded); - }} + onProgress={handleProgress} onPause={handleOnStop} onEnded={handleOnStop} muted={mute || isEchoTest} @@ -389,7 +400,7 @@ const ExternalVideoPlayer: React.FC = ({ handleReload={() => setKey(uniqueId('react-player'))} setShowHoverToolBar={setShowHoverToolBar} toolbarStyle={toolbarStyle} - handleVolumeChanged={setVolume} + handleVolumeChanged={changeVolume} volume={volume} muted={mute || isEchoTest} mutedByEchoTest={isEchoTest} @@ -413,20 +424,58 @@ const ExternalVideoPlayerContainer: React.FC = () => { /* eslint no-underscore-dangle: "off" */ // @ts-ignore - temporary while hybrid (meteor+GraphQl) const isEchoTest = useReactiveVar(audioManager._isEchoTest.value) as boolean; - const theresNoExternalVideo = useRef(true); const { data: currentUser } = useCurrentUser((user) => ({ presenter: user.presenter, })); - const currentVolume = React.useRef(0); - const isMuted = React.useRef(false); - const { data: currentMeeting } = useMeeting((m) => ({ externalVideo: m.externalVideo, layout: m.layout, })); + const currentVolume = React.useRef(0); + const isMuted = React.useRef(false); + const hasExternalVideo = useRef(false); + const lastMessageRef = useRef<{ + event: string; + rate: number; + time: number; + state?: string; + }>({ event: '', rate: 0, time: 0 }); + + const [updateExternalVideo] = useMutation(EXTERNAL_VIDEO_UPDATE); + + const sendMessage = (event: string, data: { rate: number; time: number; state?: string}) => { + // don't re-send repeated update messages + if ( + lastMessageRef.current.event === event + && Math.abs(lastMessageRef.current.time - data.time) < UPDATE_INTERVAL_THRESHOLD_MS + ) { + return; + } + + // don't register to redis a viewer joined message + if (event === 'viewerJoined') { + return; + } + + lastMessageRef.current = { ...data, event }; + + // Use an integer for playing state + // 0: stopped 1: playing + // We might use more states in the future + const state = data.state ? 1 : 0; + + updateExternalVideo({ + variables: { + status: event, + rate: data?.rate, + time: data?.time, + state, + }, + }); + }; useEffect(() => { - if (!currentMeeting?.externalVideo?.externalVideoUrl && !theresNoExternalVideo.current) { + if (!currentMeeting?.externalVideo?.externalVideoUrl && hasExternalVideo.current) { layoutContextDispatch({ type: ACTIONS.SET_PILE_CONTENT_FOR_PRESENTATION_AREA, value: { @@ -434,8 +483,8 @@ const ExternalVideoPlayerContainer: React.FC = () => { open: false, }, }); - theresNoExternalVideo.current = true; - } else if (currentMeeting?.externalVideo?.externalVideoUrl && theresNoExternalVideo.current) { + hasExternalVideo.current = false; + } else if (currentMeeting?.externalVideo?.externalVideoUrl && !hasExternalVideo.current) { layoutContextDispatch({ type: ACTIONS.SET_PILE_CONTENT_FOR_PRESENTATION_AREA, value: { @@ -443,9 +492,9 @@ const ExternalVideoPlayerContainer: React.FC = () => { open: true, }, }); - theresNoExternalVideo.current = false; + hasExternalVideo.current = true; } - }, [currentMeeting]); + }, [currentMeeting?.externalVideo?.externalVideoUrl]); // --- Plugin related code --- useEffect(() => { @@ -504,18 +553,15 @@ const ExternalVideoPlayerContainer: React.FC = () => { const { element } = fullscreen; const fullscreenContext = (element === fullscreenElementId); const [key, setKey] = React.useState(uniqueId('react-player')); - if (!currentUser || !currentMeeting) return null; + if (!currentUser || !currentMeeting?.externalVideo) return null; if (!hasExternalVideoOnLayout) return null; - const playerCurrentTime = currentMeeting.externalVideo?.playerCurrentTime ?? 0; const playerPlaybackRate = currentMeeting.externalVideo?.playerPlaybackRate ?? 1; - const playerUpdatedAt = currentMeeting.externalVideo?.updatedAt ?? Date.now(); - const playerUpdatedAtDate = new Date(playerUpdatedAt); - const currentDate = new Date(Date.now() + timeSync); - const isPaused = !currentMeeting.externalVideo?.playerPlaying ?? false; - const currentTime = isPaused ? playerCurrentTime : (((currentDate.getTime() - playerUpdatedAtDate.getTime()) / 1000) - + playerCurrentTime) * playerPlaybackRate; const isPresenter = currentUser.presenter ?? false; const isGridLayout = currentMeeting.layout?.currentLayoutType === 'VIDEO_FOCUS'; + const playing = currentMeeting.externalVideo?.playerPlaying ?? false; + const videoUrl = currentMeeting.externalVideo?.externalVideoUrl ?? ''; + + const getCurrentTime = () => calculateCurrentTime(timeSync, currentMeeting.externalVideo); return ( { isMuted={isMuted} isEchoTest={isEchoTest} isPresenter={isPresenter ?? false} - videoUrl={currentMeeting.externalVideo?.externalVideoUrl ?? ''} - playing={currentMeeting.externalVideo?.playerPlaying ?? false} - playerPlaybackRate={currentMeeting.externalVideo?.playerPlaybackRate ?? 1} + videoUrl={videoUrl} + playing={playing} + playerPlaybackRate={playerPlaybackRate} isResizing={isResizing} fullscreenContext={fullscreenContext} externalVideo={externalVideo} - currentTime={currentTime} + getCurrentTime={getCurrentTime} key={key} setKey={setKey} + sendMessage={sendMessage} /> ); }; diff --git a/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/modal/component.tsx b/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/modal/component.tsx index 202d760b5f..0e17884589 100644 --- a/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/modal/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/modal/component.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useMutation } from '@apollo/client'; import Styled from './styles'; -import SettingsSingleton from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import { isUrlValid } from './service'; import { EXTERNAL_VIDEO_START } from '../../mutations'; @@ -54,8 +54,9 @@ const ExternalVideoPlayerModal: React.FC = ({ priority, }) => { const intl = useIntl(); + const Settings = getSettingsSingletonInstance(); // @ts-ignore - settings is a js singleton - const { animations } = SettingsSingleton.application; + const { animations } = Settings.application; const [videoUrl, setVideoUrl] = React.useState(''); const [startExternalVideo] = useMutation(EXTERNAL_VIDEO_START); diff --git a/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/styles.ts b/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/styles.ts index 8cf400b89c..ec96afe4e2 100644 --- a/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/external-video-player/external-video-player-graphql/styles.ts @@ -16,6 +16,7 @@ export const Container = styled.span` position: absolute; pointer-events: inherit; background: var(--color-black); + overflow: hidden; ${({ isResizing }) => isResizing && ` pointer-events: none; diff --git a/bigbluebutton-html5/imports/ui/components/external-video-player/service.js b/bigbluebutton-html5/imports/ui/components/external-video-player/service.js deleted file mode 100644 index bc81a74102..0000000000 --- a/bigbluebutton-html5/imports/ui/components/external-video-player/service.js +++ /dev/null @@ -1,28 +0,0 @@ - -import ReactPlayer from 'react-player'; - -import Panopto from './custom-players/panopto'; - -const YOUTUBE_SHORTS_REGEX = new RegExp(/^(?:https?:\/\/)?(?:www\.)?(youtube\.com\/shorts)\/.+$/); - -const isUrlValid = (url) => { - if (YOUTUBE_SHORTS_REGEX.test(url)) { - const shortsUrl = url.replace('shorts/', 'watch?v='); - - return /^https.*$/.test(shortsUrl) && (ReactPlayer.canPlay(shortsUrl) || Panopto.canPlay(shortsUrl)); - } - - return /^https.*$/.test(url) && (ReactPlayer.canPlay(url) || Panopto.canPlay(url)); -}; - -// Convert state (Number) to playing (Boolean) -const getPlayingState = (state) => { - if (state === 1) return true; - - return false; -}; - -export { - isUrlValid, - getPlayingState, -}; diff --git a/bigbluebutton-html5/imports/ui/components/external-video-player/service.ts b/bigbluebutton-html5/imports/ui/components/external-video-player/service.ts new file mode 100644 index 0000000000..d7a799e082 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/external-video-player/service.ts @@ -0,0 +1,44 @@ +import ReactPlayer from 'react-player'; + +import { Panopto } from './custom-players/panopto'; +import { ExternalVideo } from '/imports/ui/Types/meeting'; + +const YOUTUBE_SHORTS_REGEX = new RegExp(/^(?:https?:\/\/)?(?:www\.)?(youtube\.com\/shorts)\/.+$/); + +const isUrlValid = (url: string) => { + if (YOUTUBE_SHORTS_REGEX.test(url)) { + const shortsUrl = url.replace('shorts/', 'watch?v='); + + return /^https.*$/.test(shortsUrl) && (ReactPlayer.canPlay(shortsUrl) || Panopto.canPlay(shortsUrl)); + } + + return /^https.*$/.test(url) && (ReactPlayer.canPlay(url) || Panopto.canPlay(url)); +}; + +// Convert state (Number) to playing (Boolean) +const getPlayingState = (state: number) => { + if (state === 1) return true; + + return false; +}; + +const calculateCurrentTime = (timeSync: number, externalVideoProps?: ExternalVideo) => { + const playerCurrentTime = externalVideoProps?.playerCurrentTime ?? 0; + const playerPlaybackRate = externalVideoProps?.playerPlaybackRate ?? 1; + const playerUpdatedAt = externalVideoProps?.updatedAt ?? Date.now(); + const playerUpdatedAtDate = new Date(playerUpdatedAt); + const currentDate = new Date(Date.now() + (timeSync ?? 0)); + const isPaused = !externalVideoProps?.playerPlaying; + const currentTime = isPaused + ? playerCurrentTime + : ((currentDate.getTime() - playerUpdatedAtDate.getTime()) / 1000) + + (playerCurrentTime) * playerPlaybackRate; + + return currentTime; +}; + +export { + isUrlValid, + getPlayingState, + calculateCurrentTime, +}; diff --git a/bigbluebutton-html5/imports/ui/components/generic-component-content/container.tsx b/bigbluebutton-html5/imports/ui/components/generic-component-content/container.tsx deleted file mode 100644 index f8508c3432..0000000000 --- a/bigbluebutton-html5/imports/ui/components/generic-component-content/container.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import React, { useContext, useRef } from 'react'; -import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; - -import { - layoutDispatch, - layoutSelectInput, - layoutSelectOutput, -} from '../layout/context'; -import { - DispatcherFunction, - GenericComponent as GenericComponentFromLayout, - Input, - Output, -} from '../layout/layoutTypes'; -import { PluginsContext } from '../components-data/plugin-context/context'; -import GenericComponentContent from './component'; -import { ACTIONS, PRESENTATION_AREA } from '../layout/enums'; -import getDifferenceBetweenLists from './utils'; -import { GenericComponentContainerProps } from './types'; - -const GenericComponentContainer: React.FC = (props: GenericComponentContainerProps) => { - const { genericComponentId } = props; - - const previousPluginGenericComponents = useRef([]); - const { - pluginsExtensibleAreasAggregatedState, - } = useContext(PluginsContext); - const layoutContextDispatch: DispatcherFunction = layoutDispatch(); - let genericComponentExtensibleArea = [] as PluginSdk.GenericComponent[]; - - if (pluginsExtensibleAreasAggregatedState.genericComponents) { - genericComponentExtensibleArea = [ - ...pluginsExtensibleAreasAggregatedState.genericComponents as PluginSdk.GenericComponent[], - ]; - const [ - genericComponentsAdded, - genericComponentsRemoved, - ] = getDifferenceBetweenLists(previousPluginGenericComponents.current, genericComponentExtensibleArea); - if (genericComponentsAdded.length > 0 || genericComponentsRemoved.length > 0) { - previousPluginGenericComponents.current = [...genericComponentExtensibleArea]; - genericComponentsAdded.forEach((g) => { - layoutContextDispatch({ - type: ACTIONS.SET_PILE_CONTENT_FOR_PRESENTATION_AREA, - value: { - content: PRESENTATION_AREA.GENERIC_COMPONENT, - open: true, - genericComponentId: g.id, - }, - }); - }); - genericComponentsRemoved.forEach((g) => { - layoutContextDispatch({ - type: ACTIONS.SET_PILE_CONTENT_FOR_PRESENTATION_AREA, - value: { - content: PRESENTATION_AREA.GENERIC_COMPONENT, - open: false, - genericComponentId: g.id, - }, - }); - }); - } - } - - const genericComponentLayoutInformation: GenericComponentFromLayout = layoutSelectOutput( - (i: Output) => i.genericComponent, - ); - - const cameraDock = layoutSelectInput((i: Input) => i.cameraDock); - const { isResizing } = cameraDock; - - if (!genericComponentExtensibleArea - || genericComponentExtensibleArea.length === 0 - || !genericComponentId) return null; - return ( - - ); -}; - -export default GenericComponentContainer; diff --git a/bigbluebutton-html5/imports/ui/components/generic-component-content/types.ts b/bigbluebutton-html5/imports/ui/components/generic-component-content/types.ts deleted file mode 100644 index 5093d1aab3..0000000000 --- a/bigbluebutton-html5/imports/ui/components/generic-component-content/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GenericComponent } from 'bigbluebutton-html-plugin-sdk'; -import { GenericComponent as GenericComponentLayout } from '../layout/layoutTypes'; - -export interface GenericComponentContainerProps { - genericComponentId: string; -} -export interface GenericComponentProps { - isResizing: boolean; - genericComponentId: string; - genericComponentLayoutInformation: GenericComponentLayout; - renderFunctionComponents: GenericComponent[]; -} diff --git a/bigbluebutton-html5/imports/ui/components/generic-component-content/generic-component-item/component.tsx b/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/component.tsx similarity index 67% rename from bigbluebutton-html5/imports/ui/components/generic-component-content/generic-component-item/component.tsx rename to bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/component.tsx index 1e35d7f30f..4304bc57a7 100644 --- a/bigbluebutton-html5/imports/ui/components/generic-component-content/generic-component-item/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/component.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useRef } from 'react'; -import { GenericComponentItemProps } from './types'; +import { GenericContentItemProps } from './types'; -const GenericComponentItem: React.FC = (props) => { +const GenericContentItem: React.FC = (props) => { const { renderFunction, } = props; @@ -16,6 +16,7 @@ const GenericComponentItem: React.FC = (props) => { return (
= (props) => { ); }; -export default GenericComponentItem; +export default GenericContentItem; diff --git a/bigbluebutton-html5/imports/ui/components/generic-component-content/generic-component-item/types.ts b/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/types.ts similarity index 54% rename from bigbluebutton-html5/imports/ui/components/generic-component-content/generic-component-item/types.ts rename to bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/types.ts index cc36ade751..cce3db6ecb 100644 --- a/bigbluebutton-html5/imports/ui/components/generic-component-content/generic-component-item/types.ts +++ b/bigbluebutton-html5/imports/ui/components/generic-content/generic-content-item/types.ts @@ -1,3 +1,3 @@ -export interface GenericComponentItemProps { +export interface GenericContentItemProps { renderFunction: (element: HTMLElement) => void; } diff --git a/bigbluebutton-html5/imports/ui/components/generic-component-content/component.tsx b/bigbluebutton-html5/imports/ui/components/generic-content/generic-main-content/component.tsx similarity index 58% rename from bigbluebutton-html5/imports/ui/components/generic-component-content/component.tsx rename to bigbluebutton-html5/imports/ui/components/generic-content/generic-main-content/component.tsx index fec14ab584..44be036589 100644 --- a/bigbluebutton-html5/imports/ui/components/generic-component-content/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/generic-content/generic-main-content/component.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import * as Styled from './styles'; -import { GenericComponentProps } from './types'; -import GenericComponentItem from './generic-component-item/component'; +import * as Styled from '../styles'; +import { GenericContentMainAreaProps } from '../types'; +import GenericContentItem from '../generic-content-item/component'; -const GenericComponentContent: React.FC = ({ +const GenericMainContent: React.FC = ({ isResizing, - genericComponentLayoutInformation, + genericContentLayoutInformation, renderFunctionComponents, - genericComponentId, + genericContentId, }) => { const { height, @@ -15,11 +15,11 @@ const GenericComponentContent: React.FC = ({ top, left, right, - } = genericComponentLayoutInformation; + } = genericContentLayoutInformation; const isMinimized = width === 0 && height === 0; - const componentToRender = renderFunctionComponents.filter((g) => genericComponentId === g.id); + const componentToRender = renderFunctionComponents.filter((g) => genericContentId === g.id); return ( = ({ isResizing={isResizing} isMinimized={isMinimized} > - @@ -40,4 +40,4 @@ const GenericComponentContent: React.FC = ({ ); }; -export default GenericComponentContent; +export default GenericMainContent; diff --git a/bigbluebutton-html5/imports/ui/components/generic-content/generic-main-content/container.tsx b/bigbluebutton-html5/imports/ui/components/generic-content/generic-main-content/container.tsx new file mode 100644 index 0000000000..f9a6159c4f --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/generic-content/generic-main-content/container.tsx @@ -0,0 +1,92 @@ +import React, { useContext, useRef } from 'react'; +import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; + +import { + layoutDispatch, + layoutSelectInput, + layoutSelectOutput, +} from '/imports/ui/components/layout/context'; +import { + DispatcherFunction, + GenericContentMainArea as GenericContentMainAreaFromLayout, + Input, + Output, +} from '/imports/ui/components/layout/layoutTypes'; +import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; +import { GenericContentType } from 'bigbluebutton-html-plugin-sdk/dist/cjs/extensible-areas/generic-content-item/enums'; +import GenericMainContent from './component'; +import { ACTIONS, PRESENTATION_AREA } from '/imports/ui/components/layout/enums'; +import getDifferenceBetweenLists from '../utils'; +import { GenericContentMainAreaContainerProps } from '../types'; + +const GenericContentMainAreaContainer: React.FC = ( + props: GenericContentMainAreaContainerProps, +) => { + const { genericMainContentId } = props; + + const previousPluginGenericContainerContents = useRef([]); + const { + pluginsExtensibleAreasAggregatedState, + } = useContext(PluginsContext); + const layoutContextDispatch: DispatcherFunction = layoutDispatch(); + let genericContainerContentExtensibleArea = [] as PluginSdk.GenericContentMainArea[]; + + if (pluginsExtensibleAreasAggregatedState.genericContentItems) { + const genericContainerContent = pluginsExtensibleAreasAggregatedState.genericContentItems + .filter((g) => g.type === GenericContentType.MAIN_AREA) as PluginSdk.GenericContentMainArea[]; + genericContainerContentExtensibleArea = [ + ...genericContainerContent, + ]; + const [ + genericContentItemsAdded, + genericContentItemsRemoved, + ] = getDifferenceBetweenLists( + previousPluginGenericContainerContents.current, + genericContainerContentExtensibleArea, + ); + if (genericContentItemsAdded.length > 0 || genericContentItemsRemoved.length > 0) { + previousPluginGenericContainerContents.current = [...genericContainerContentExtensibleArea]; + genericContentItemsAdded.forEach((g) => { + layoutContextDispatch({ + type: ACTIONS.SET_PILE_CONTENT_FOR_PRESENTATION_AREA, + value: { + content: PRESENTATION_AREA.GENERIC_CONTENT, + open: true, + genericContentId: g.id, + }, + }); + }); + genericContentItemsRemoved.forEach((g) => { + layoutContextDispatch({ + type: ACTIONS.SET_PILE_CONTENT_FOR_PRESENTATION_AREA, + value: { + content: PRESENTATION_AREA.GENERIC_CONTENT, + open: false, + genericContentId: g.id, + }, + }); + }); + } + } + + const genericContentLayoutInformation: GenericContentMainAreaFromLayout = layoutSelectOutput( + (i: Output) => i.genericMainContent, + ); + + const cameraDock = layoutSelectInput((i: Input) => i.cameraDock); + const { isResizing } = cameraDock; + + if (!genericContainerContentExtensibleArea + || genericContainerContentExtensibleArea.length === 0 + || !genericMainContentId) return null; + return ( + + ); +}; + +export default GenericContentMainAreaContainer; diff --git a/bigbluebutton-html5/imports/ui/components/generic-content/generic-sidekick-content/component.tsx b/bigbluebutton-html5/imports/ui/components/generic-content/generic-sidekick-content/component.tsx new file mode 100644 index 0000000000..0489b02ecb --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/generic-content/generic-sidekick-content/component.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import Styled from './styles'; +import { GenericSidekickContentProps } from '../types'; +import GenericContentItem from '../generic-content-item/component'; +import { PANELS, ACTIONS } from '/imports/ui/components/layout/enums'; + +const GenericSidekickContent: React.FC = ({ + renderFunction, + layoutContextDispatch, + genericContentId, + genericContentLabel, +}) => ( + + { + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, + value: false, + }); + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, + value: PANELS.NONE, + }); + }, + 'data-test': `hide_${genericContentId}`, + 'aria-label': genericContentLabel, + label: genericContentLabel, + }} + customRightButton={null} + /> + + +); + +export default GenericSidekickContent; diff --git a/bigbluebutton-html5/imports/ui/components/generic-content/generic-sidekick-content/container.tsx b/bigbluebutton-html5/imports/ui/components/generic-content/generic-sidekick-content/container.tsx new file mode 100644 index 0000000000..05b9bb7fbc --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/generic-content/generic-sidekick-content/container.tsx @@ -0,0 +1,61 @@ +import React, { useContext } from 'react'; +import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; +import { GenericContentType } from 'bigbluebutton-html-plugin-sdk/dist/cjs/extensible-areas/generic-content-item/enums'; +import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; +import { PANELS, ACTIONS } from '/imports/ui/components/layout/enums'; +import GenericSidekickContent from './component'; +import { GenericContentSidekickContainerProps } from '../types'; +import logger from '/imports/startup/client/logger'; +import { layoutDispatch } from '../../layout/context'; + +const GenericContentSidekickContainer: React.FC = ( + props: GenericContentSidekickContainerProps, +) => { + const { genericSidekickContentId } = props; + const genericSidekickContentIdIsolated = genericSidekickContentId.replace(PANELS.GENERIC_CONTENT_SIDEKICK, ''); + const layoutContextDispatch = layoutDispatch(); + + const { + pluginsExtensibleAreasAggregatedState, + } = useContext(PluginsContext); + let genericContentSidekickAreaExtensibleArea = [] as PluginSdk.GenericContentSidekickArea[]; + + if (pluginsExtensibleAreasAggregatedState.genericContentItems) { + const genericContentSidekickArea = pluginsExtensibleAreasAggregatedState.genericContentItems + .filter((g) => g.type === GenericContentType.SIDEKICK_AREA) as PluginSdk.GenericContentSidekickArea[]; + genericContentSidekickAreaExtensibleArea = [...genericContentSidekickArea]; + } + + const pickedGenericSidekickContent = genericContentSidekickAreaExtensibleArea + .filter((gsc) => gsc.id === genericSidekickContentIdIsolated)[0]; + + if (genericContentSidekickAreaExtensibleArea.length === 0 || !pickedGenericSidekickContent) { + logger.error({ + logCode: 'generic_sidekick_content_not_found', + extraInfo: { + genericSidekickContentId, + genericSidekickContentIdIsolated, + }, + }, `Generic sidekick content with id ${genericSidekickContentIdIsolated} not found`); + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, + value: false, + }); + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, + value: PANELS.NONE, + }); + return null; + } + + return ( + + ); +}; + +export default GenericContentSidekickContainer; diff --git a/bigbluebutton-html5/imports/ui/components/generic-content/generic-sidekick-content/styles.ts b/bigbluebutton-html5/imports/ui/components/generic-content/generic-sidekick-content/styles.ts new file mode 100644 index 0000000000..437c0ed4c2 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/generic-content/generic-sidekick-content/styles.ts @@ -0,0 +1,33 @@ +import styled from 'styled-components'; +import { + mdPaddingX, +} from '/imports/ui/stylesheets/styled-components/general'; +import { colorWhite } from '/imports/ui/stylesheets/styled-components/palette'; +import { smallOnly } from '/imports/ui/stylesheets/styled-components/breakpoints'; +import CommonHeader from '/imports/ui/components/common/control-header/component'; + +const Container = styled.div` + background-color: ${colorWhite}; + padding: ${mdPaddingX}; + display: flex; + flex-grow: 1; + flex-direction: column; + overflow: hidden; + height: 100%; + + @media ${smallOnly} { + transform: none !important; + &.no-padding { + padding: 0; + } + } +`; + +const Header = styled(CommonHeader)` + padding-bottom: .2rem; +`; + +export default { + Container, + Header, +}; diff --git a/bigbluebutton-html5/imports/ui/components/generic-component-content/styles.ts b/bigbluebutton-html5/imports/ui/components/generic-content/styles.ts similarity index 100% rename from bigbluebutton-html5/imports/ui/components/generic-component-content/styles.ts rename to bigbluebutton-html5/imports/ui/components/generic-content/styles.ts diff --git a/bigbluebutton-html5/imports/ui/components/generic-content/types.ts b/bigbluebutton-html5/imports/ui/components/generic-content/types.ts new file mode 100644 index 0000000000..d564264ec2 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/generic-content/types.ts @@ -0,0 +1,24 @@ +import { GenericContentMainArea } from 'bigbluebutton-html-plugin-sdk'; +import { GenericContentMainArea as GenericContentMainAreaLayout } from '../layout/layoutTypes'; + +export interface GenericContentMainAreaContainerProps { + genericMainContentId: string; +} + +export interface GenericContentMainAreaProps { + isResizing: boolean; + genericContentId: string; + genericContentLayoutInformation: GenericContentMainAreaLayout; + renderFunctionComponents: GenericContentMainArea[]; +} + +export interface GenericContentSidekickContainerProps { + genericSidekickContentId: string; +} + +export interface GenericSidekickContentProps { + layoutContextDispatch: (...args: unknown[]) => void; + genericContentId: string; + renderFunction: (element: HTMLElement) => void; + genericContentLabel: string; +} diff --git a/bigbluebutton-html5/imports/ui/components/generic-component-content/utils.ts b/bigbluebutton-html5/imports/ui/components/generic-content/utils.ts similarity index 100% rename from bigbluebutton-html5/imports/ui/components/generic-component-content/utils.ts rename to bigbluebutton-html5/imports/ui/components/generic-content/utils.ts diff --git a/bigbluebutton-html5/imports/ui/components/join-handler/custom-users-settings/component.tsx b/bigbluebutton-html5/imports/ui/components/join-handler/custom-users-settings/component.tsx index 499fab36db..ab4e4deccd 100644 --- a/bigbluebutton-html5/imports/ui/components/join-handler/custom-users-settings/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/join-handler/custom-users-settings/component.tsx @@ -1,6 +1,6 @@ import { useQuery } from '@apollo/client'; import React, { useEffect } from 'react'; -import { UserCustomParameterResponse, getCustomParameter } from './queries'; +import { UserMetadataResponse, getUserMetadata } from './queries'; import { setUserSettings } from '/imports/ui/core/local-states/useUserSettings'; interface CustomUsersSettingsProps { @@ -11,14 +11,14 @@ const CustomUsersSettings: React.FC = ({ children, }) => { const { - data: customParameterData, - loading: customParameterLoading, - error: customParameterError, - } = useQuery(getCustomParameter); + data: userMetadataData, + loading: userMetadataLoading, + error: userMetadataError, + } = useQuery(getUserMetadata); const [allowToRender, setAllowToRender] = React.useState(false); useEffect(() => { - if (customParameterData && !customParameterLoading) { - const filteredData = customParameterData.user_customParameter.map((uc) => { + if (userMetadataData && !userMetadataLoading) { + const filteredData = userMetadataData.user_metadata.map((uc) => { const { parameter, value } = uc; let parsedValue: string | boolean | string[] = ''; try { @@ -32,15 +32,15 @@ const CustomUsersSettings: React.FC = ({ setAllowToRender(true); } }, [ - customParameterData, - customParameterLoading, + userMetadataData, + userMetadataLoading, ]); useEffect(() => { - if (customParameterError) { - throw new Error(`Error on requesting custom parameter data: ${customParameterError}`); + if (userMetadataError) { + throw new Error(`Error on requesting custom parameter data: ${userMetadataError}`); } - }, [customParameterError]); + }, [userMetadataError]); return allowToRender ? <>{children} : null; }; diff --git a/bigbluebutton-html5/imports/ui/components/join-handler/custom-users-settings/queries.ts b/bigbluebutton-html5/imports/ui/components/join-handler/custom-users-settings/queries.ts index 7297febdf2..a54436fc57 100644 --- a/bigbluebutton-html5/imports/ui/components/join-handler/custom-users-settings/queries.ts +++ b/bigbluebutton-html5/imports/ui/components/join-handler/custom-users-settings/queries.ts @@ -1,17 +1,17 @@ import { gql } from '@apollo/client'; -interface CustomParameter { +interface UserMetadata { parameter: string; value: string; } -export interface UserCustomParameterResponse { - user_customParameter: CustomParameter[]; +export interface UserMetadataResponse { + user_metadata: UserMetadata[]; } -export const getCustomParameter = gql` - query getCustomParameter { - user_customParameter { +export const getUserMetadata = gql` + query getUserMetadata { + user_metadata { parameter value } @@ -19,5 +19,5 @@ export const getCustomParameter = gql` `; export default { - getCustomParameter, + getUserMetadata, }; diff --git a/bigbluebutton-html5/imports/ui/components/join-handler/guest-wait/component.tsx b/bigbluebutton-html5/imports/ui/components/join-handler/guest-wait/component.tsx new file mode 100644 index 0000000000..364a46f26b --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/join-handler/guest-wait/component.tsx @@ -0,0 +1,199 @@ +import React, { + useCallback, + useContext, + useEffect, + useRef, + useState, +} from 'react'; +import { defineMessages, useIntl } from 'react-intl'; +import { LoadingContext } from '../../common/loading-screen/loading-screen-HOC/component'; +import Styled from './styles'; + +const REDIRECT_TIMEOUT = 15000; + +export const GUEST_STATUSES = { + ALLOW: 'ALLOW', + DENY: 'DENY', + WAIT: 'WAIT', +}; + +const intlMessages = defineMessages({ + windowTitle: { + id: 'app.guest.windowTitle', + description: 'tab title', + }, + guestWait: { + id: 'app.guest.guestWait', + description: '', + }, + noSessionToken: { + id: 'app.guest.noSessionToken', + description: '', + }, + guestInvalid: { + id: 'app.guest.guestInvalid', + description: '', + }, + allow: { + id: 'app.guest.allow', + description: '', + }, + deny: { + id: 'app.guest.guestDeny', + description: '', + }, + firstPosition: { + id: 'app.guest.firstPositionInWaitingQueue', + description: '', + }, + position: { + id: 'app.guest.positionInWaitingQueue', + description: '', + }, + calculating: { + id: 'app.guest.calculating', + description: '', + }, +}); + +function getSearchParam(name: string) { + const params = new URLSearchParams(window.location.search); + + if (params && params.has(name)) { + const param = params.get(name); + + return param; + } + + return null; +} + +interface GuestWaitProps { + guestStatus: string | null; + guestLobbyMessage: string | null; + positionInWaitingQueue: number | null; + logoutUrl: string; +} + +const GuestWait: React.FC = (props) => { + const { + guestLobbyMessage, + guestStatus, + logoutUrl, + positionInWaitingQueue, + } = props; + + const intl = useIntl(); + const [animate, setAnimate] = useState(true); + const [message, setMessage] = useState(intl.formatMessage(intlMessages.guestWait)); + const [positionMessage, setPositionMessage] = useState(intl.formatMessage(intlMessages.calculating)); + const lobbyMessageRef = useRef(''); + const positionInWaitingQueueRef = useRef(''); + const loadingContextInfo = useContext(LoadingContext); + + const updateLobbyMessage = useCallback((message: string | null) => { + if (!message) { + setMessage(intl.formatMessage(intlMessages.guestWait)); + return; + } + if (message !== lobbyMessageRef.current) { + lobbyMessageRef.current = message; + if (lobbyMessageRef.current.length !== 0) { + setMessage(lobbyMessageRef.current); + } else { + setMessage(intl.formatMessage(intlMessages.guestWait)); + } + } + }, [intl]); + + const updatePositionInWaitingQueue = useCallback((newPositionInWaitingQueue: number) => { + if (positionInWaitingQueueRef.current !== newPositionInWaitingQueue.toString()) { + positionInWaitingQueueRef.current = newPositionInWaitingQueue.toString(); + if (positionInWaitingQueueRef.current === '1') { + setPositionMessage(intl.formatMessage(intlMessages.firstPosition)); + } else { + setPositionMessage(intl.formatMessage(intlMessages.position) + positionInWaitingQueueRef.current); + } + } + }, [intl]); + + useEffect(() => { + document.title = intl.formatMessage(intlMessages.windowTitle); + }, []); + + useEffect(() => { + const sessionToken = getSearchParam('sessionToken'); + + if (loadingContextInfo.isLoading) { + loadingContextInfo.setLoading(false, ''); + } + + if (!sessionToken) { + setAnimate(false); + setMessage(intl.formatMessage(intlMessages.noSessionToken)); + return; + } + + if (!guestStatus) { + setAnimate(false); + setPositionMessage(''); + setMessage(intl.formatMessage(intlMessages.guestInvalid)); + return; + } + + if (guestStatus === GUEST_STATUSES.ALLOW) { + setPositionMessage(''); + updateLobbyMessage(intl.formatMessage(intlMessages.allow)); + setAnimate(false); + return; + } + + if (guestStatus === GUEST_STATUSES.DENY) { + setAnimate(false); + setPositionMessage(''); + setMessage(intl.formatMessage(intlMessages.deny)); + setTimeout(() => { + window.location.assign(logoutUrl); + }, REDIRECT_TIMEOUT); + return; + } + + // WAIT + updateLobbyMessage(guestLobbyMessage || ''); + if (positionInWaitingQueue) { + updatePositionInWaitingQueue(positionInWaitingQueue); + } + }, [ + guestLobbyMessage, + guestStatus, + logoutUrl, + positionInWaitingQueue, + intl, + updateLobbyMessage, + updatePositionInWaitingQueue, + ]); + + return ( + + + 3/5 + {intl.formatMessage(intlMessages.windowTitle)} + {animate && ( + + + + + + )} +

+ {message} +

+ +

{positionMessage}

+
+
+
+ ); +}; + +export default GuestWait; diff --git a/bigbluebutton-html5/imports/ui/components/join-handler/guest-wait/styles.ts b/bigbluebutton-html5/imports/ui/components/join-handler/guest-wait/styles.ts new file mode 100644 index 0000000000..77e7f9dd4c --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/join-handler/guest-wait/styles.ts @@ -0,0 +1,71 @@ +import styled, { keyframes } from 'styled-components'; + +const Container = styled.div` + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; +`; + +const Content = styled.div` + text-align: center; + color: white; + font-weight: bold; + font-size: 24px; +`; + +const Heading = styled.h1` + font-size: 2rem; +`; + +const Position = styled.div` + align-items: center; + text-align: center; +`; + +const sk_bouncedelay = keyframes` + 0%, + 80%, + 100% { + transform: scale(0); + } + + 40% { + transform: scale(1.0); + } +`; + +const Spinner = styled.div` + margin: 20px auto; + font-size: 0px; +`; + +const Bounce = styled.div` + width: 18px; + height: 18px; + margin: 0 5px; + background-color: rgb(255, 255, 255); + display: inline-block; + border-radius: 100%; + animation: ${sk_bouncedelay} calc(1.4s) infinite ease-in-out both; +`; + +const Bounce1 = styled(Bounce)` + animation-delay: -0.32s; +`; + +const Bounce2 = styled(Bounce)` + animation-delay: -0.16s; +`; + +export default { + Container, + Content, + Heading, + Position, + Bounce, + Bounce1, + Bounce2, + Spinner, +}; diff --git a/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/component.tsx b/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/component.tsx index 065e153b6b..0cac341509 100644 --- a/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/component.tsx @@ -1,6 +1,6 @@ -import { useMutation, useQuery, useSubscription } from '@apollo/client'; -import React, { useContext, useEffect } from 'react'; -import { Session } from 'meteor/session'; +import { useMutation, useQuery } from '@apollo/client'; +import React, { useContext, useEffect, useState } from 'react'; +import Session from '/imports/ui/services/storage/in-memory'; import { getUserCurrent, GetUserCurrentResponse, @@ -12,8 +12,13 @@ import { setAuthData } from '/imports/ui/core/local-states/useAuthData'; import MeetingEndedContainer from '../../meeting-ended/component'; import { setUserDataToSessionStorage } from './service'; import { LoadingContext } from '../../common/loading-screen/loading-screen-HOC/component'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; +import logger from '/imports/startup/client/logger'; +import deviceInfo from '/imports/utils/deviceInfo'; +import GuestWaitContainer, { GUEST_STATUSES } from '../guest-wait/component'; const connectionTimeout = 60000; +const MESSAGE_TIMEOUT = 3000; interface PresenceManagerContainerProps { children: React.ReactNode; @@ -37,7 +42,11 @@ interface PresenceManagerProps extends PresenceManagerContainerProps { bannerColor: string; bannerText: string; customLogoUrl: string; + customDarkLogoUrl: string; loggedOut: boolean; + guestStatus: string; + guestLobbyMessage: string | null; + positionInWaitingQueue: number | null; } const PresenceManager: React.FC = ({ @@ -59,19 +68,30 @@ const PresenceManager: React.FC = ({ bannerColor, bannerText, customLogoUrl, + customDarkLogoUrl, loggedOut, + guestLobbyMessage, + guestStatus, + positionInWaitingQueue, }) => { const [allowToRender, setAllowToRender] = React.useState(false); const [dispatchUserJoin] = useMutation(userJoinMutation); const timeoutRef = React.useRef>(); const loadingContextInfo = useContext(LoadingContext); + const [isGuestAllowed, setIsGuestAllowed] = useState(guestStatus === GUEST_STATUSES.ALLOW); useEffect(() => { - timeoutRef.current = setTimeout(() => { - loadingContextInfo.setLoading(false, ''); - throw new Error('Authentication timeout'); - }, connectionTimeout); + const allowed = guestStatus === GUEST_STATUSES.ALLOW; + if (allowed) { + setTimeout(() => { + setIsGuestAllowed(true); + }, MESSAGE_TIMEOUT); + } else { + setIsGuestAllowed(false); + } + }, [guestStatus]); + useEffect(() => { const urlParams = new URLSearchParams(window.location.search); const sessionToken = urlParams.get('sessionToken') as string; setAuthData({ @@ -94,26 +114,37 @@ const PresenceManager: React.FC = ({ extId, meetingName, customLogoUrl, + customDarkLogoUrl, }); }, []); + useEffect(() => { + if (isGuestAllowed) { + timeoutRef.current = setTimeout(() => { + loadingContextInfo.setLoading(false, ''); + throw new Error('Authentication timeout'); + }, connectionTimeout); + } + }, [isGuestAllowed]); + useEffect(() => { if (bannerColor || bannerText) { - Session.set('bannerText', bannerText); - Session.set('bannerColor', bannerColor); + Session.setItem('bannerText', bannerText); + Session.setItem('bannerColor', bannerColor); } }, [bannerColor, bannerText]); useEffect(() => { - if (authToken && !joined) { + if (authToken && !joined && isGuestAllowed) { dispatchUserJoin({ variables: { authToken, clientType: 'HTML5', + clientIsMobile: deviceInfo.isMobile, }, }); } - }, [joined, authToken]); + }, [joined, authToken, isGuestAllowed]); useEffect(() => { if (joined) { @@ -145,12 +176,24 @@ const PresenceManager: React.FC = ({ ) : null } + { + !isGuestAllowed && !(meetingEnded || joinErrorCode || ejectReasonCode || loggedOut) + ? ( + + ) + : null + } ); }; const PresenceManagerContainer: React.FC = ({ children }) => { - const { loading, error, data } = useSubscription(getUserCurrent); + const { loading, error, data } = useDeduplicatedSubscription(getUserCurrent); const { loading: userInfoLoading, @@ -162,7 +205,7 @@ const PresenceManagerContainer: React.FC = ({ chi if (loading || userInfoLoading) return null; if (error || userInfoError) { loadingContextInfo.setLoading(false, ''); - throw new Error('Error on user authentication: ', error); + logger.debug(`Error on user authentication: ${error}`); } if (!data || data.user_current.length === 0) return null; @@ -177,6 +220,8 @@ const PresenceManagerContainer: React.FC = ({ chi ejectReasonCode, meeting, loggedOut, + guestStatusDetails, + guestStatus, } = data.user_current[0]; const { logoutUrl, @@ -185,6 +230,7 @@ const PresenceManagerContainer: React.FC = ({ chi bannerColor, bannerText, customLogoUrl, + customDarkLogoUrl, } = userInfoData.meeting[0]; const { extId, name: userName, userId } = userInfoData.user_current[0]; @@ -208,6 +254,10 @@ const PresenceManagerContainer: React.FC = ({ chi bannerText={bannerText} loggedOut={loggedOut} customLogoUrl={customLogoUrl} + customDarkLogoUrl={customDarkLogoUrl} + guestLobbyMessage={guestStatusDetails?.guestLobbyMessage ?? null} + positionInWaitingQueue={guestStatusDetails?.positionInWaitingQueue ?? null} + guestStatus={guestStatus} > {children} diff --git a/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/queries.ts b/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/queries.ts index bb9e619b60..577f35e32f 100644 --- a/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/queries.ts +++ b/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/queries.ts @@ -9,10 +9,17 @@ export interface GetUserCurrentResponse { joinErrorMessage: string; ejectReasonCode: string; loggedOut: boolean; + guestStatus: string; + guestStatusDetails: { + guestLobbyMessage: string | null; + positionInWaitingQueue: number; + isAllowed: boolean; + } | null; meeting: { ended: boolean; endedReasonCode: string; endedByUserName: string; + logoutUrl: string; }; }>; } @@ -25,6 +32,7 @@ export interface GetUserInfoResponse { bannerColor: string; bannerText: string; customLogoUrl: string; + customDarkLogoUrl: string; }>; user_current: Array<{ extId: string; @@ -42,6 +50,7 @@ query getUserInfo { bannerColor bannerText customLogoUrl + customDarkLogoUrl } user_current { extId @@ -61,19 +70,27 @@ subscription getUserCurrent { joined ejectReasonCode loggedOut + guestStatus meeting { ended endedReasonCode endedByUserName + logoutUrl + } + guestStatusDetails { + guestLobbyMessage + positionInWaitingQueue + isAllowed } } } `; export const userJoinMutation = gql` -mutation UserJoin($authToken: String!, $clientType: String!) { +mutation UserJoin($authToken: String!, $clientType: String!, $clientIsMobile: Boolean!) { userJoinMeeting( authToken: $authToken, clientType: $clientType, + clientIsMobile: $clientIsMobile, ) } `; diff --git a/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/service.ts b/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/service.ts index b616f6a1bf..d6f27df973 100644 --- a/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/service.ts +++ b/bigbluebutton-html5/imports/ui/components/join-handler/presenceManager/service.ts @@ -1,3 +1,5 @@ +import Storage from '/imports/ui/services/storage/session'; + export const JoinErrorCodeTable = { NOT_EJECT: 'not_eject_reason', DUPLICATE_USER: 'duplicate_user_in_meeting_eject_reason', @@ -21,6 +23,7 @@ export const setUserDataToSessionStorage = (userData: { extId: string, meetingName: string, customLogoUrl: string, + customDarkLogoUrl: string, }) => { sessionStorage.setItem('meetingId', userData.meetingId); sessionStorage.setItem('userId', userData.userId); @@ -29,7 +32,8 @@ export const setUserDataToSessionStorage = (userData: { sessionStorage.setItem('userName', userData.userName); sessionStorage.setItem('extId', userData.extId); sessionStorage.setItem('meetingName', userData.meetingName); - sessionStorage.setItem('CustomLogoUrl', userData.customLogoUrl); + Storage.setItem('CustomLogoUrl', userData.customLogoUrl); + Storage.setItem('CustomDarkLogoUrl', userData.customDarkLogoUrl); }; export default { diff --git a/bigbluebutton-html5/imports/ui/components/layout/context.jsx b/bigbluebutton-html5/imports/ui/components/layout/context.jsx index e2b76b5a3a..6e61e243c4 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/context.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/context.jsx @@ -1,7 +1,6 @@ import React, { useEffect, useReducer, useRef } from 'react'; import { createContext, useContextSelector } from 'use-context-selector'; import PropTypes from 'prop-types'; -import { useSubscription } from '@apollo/client'; import { equals } from 'ramda'; import { PINNED_PAD_SUBSCRIPTION } from '/imports/ui/components/notes/queries'; import { @@ -10,7 +9,10 @@ import { import DEFAULT_VALUES from '/imports/ui/components/layout/defaultValues'; import { INITIAL_INPUT_STATE, INITIAL_OUTPUT_STATE } from './initState'; import useUpdatePresentationAreaContentForPlugin from '/imports/ui/components/plugins-engine/ui-data-hooks/layout/presentation-area/utils'; -import { isPresentationEnabled } from '/imports/ui/services/features'; +import { useIsPresentationEnabled } from '/imports/ui/services/features'; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; +import { usePrevious } from '../whiteboard/utils'; +import Session from '/imports/ui/services/storage/in-memory'; // variable to debug in console log const debug = false; @@ -42,16 +44,13 @@ const initPresentationAreaContentActions = [{ }, }]; -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id; - const initState = { presentationAreaContentActions: initPresentationAreaContentActions, deviceType: null, - isRTL: false, + isRTL: DEFAULT_VALUES.isRTL, layoutType: DEFAULT_VALUES.layoutType, fontSize: DEFAULT_VALUES.fontSize, - idChatOpen: DEFAULT_VALUES.idChatOpen, + idChatOpen: '', fullscreen: { element: '', group: '', @@ -85,7 +84,7 @@ const reducer = (state, action) => { if (state.input === action.value) return state; return { ...state, - input: action.value, + input: typeof action.value === 'function' ? action.value(state.input) : action.value, }; } @@ -1204,24 +1203,24 @@ const reducer = (state, action) => { } // GENERIC COMPONENT - case ACTIONS.SET_HAS_GENERIC_COMPONENT: { - const { genericComponent } = state.input; - if (genericComponent.genericComponentId === action.value) { + case ACTIONS.SET_HAS_GENERIC_CONTENT: { + const { genericMainContent } = state.input; + if (genericMainContent.genericContentId === action.value) { return state; } return { ...state, input: { ...state.input, - genericComponent: { - ...genericComponent, - genericComponentId: action.value, + genericMainContent: { + ...genericMainContent, + genericContentId: action.value, }, }, }; } - case ACTIONS.SET_GENERIC_COMPONENT_OUTPUT: { + case ACTIONS.SET_GENERIC_CONTENT_OUTPUT: { const { width, height, @@ -1229,20 +1228,20 @@ const reducer = (state, action) => { left, right, } = action.value; - const { genericComponent } = state.output; - if (genericComponent.width === width - && genericComponent.height === height - && genericComponent.top === top - && genericComponent.left === left - && genericComponent.right === right) { + const { genericMainContent } = state.output; + if (genericMainContent.width === width + && genericMainContent.height === height + && genericMainContent.top === top + && genericMainContent.left === left + && genericMainContent.right === right) { return state; } return { ...state, output: { ...state.output, - genericComponent: { - ...genericComponent, + genericMainContent: { + ...genericMainContent, width, height, top, @@ -1306,21 +1305,28 @@ const reducer = (state, action) => { if (action.value.open) { presentationAreaContentActions.push(action); } else { - const indexOfOpenedContent = presentationAreaContentActions.findIndex((p) => { - if (action.value.content === PRESENTATION_AREA.GENERIC_COMPONENT) { - return ( + let indexesOfOpenedContent = presentationAreaContentActions.reduce((indexes, p, index) => { + if (action.value.content === PRESENTATION_AREA.GENERIC_CONTENT) { + if ( p.value.content === action.value.content - && p.value.open - && p.value.genericComponentId === action.value.genericComponentId - ); + && p.value.open + && p.value.genericContentId === action.value.genericContentId + ) { + indexes.push(index); + } + } else if (p.value.content === action.value.content && p.value.open) { + indexes.push(index); } - return ( - p.value.content === action.value.content && p.value.open - ); - }); + return indexes; + }, []); + indexesOfOpenedContent = indexesOfOpenedContent.length > 0 ? indexesOfOpenedContent : -1; if ( - indexOfOpenedContent !== -1 - ) presentationAreaContentActions.splice(indexOfOpenedContent, 1); + indexesOfOpenedContent !== -1 + ) { + indexesOfOpenedContent.reverse().forEach((index) => { + presentationAreaContentActions.splice(index, 1); + }); + } } return { ...state, @@ -1335,8 +1341,10 @@ const reducer = (state, action) => { const updatePresentationAreaContent = ( layoutContextState, + previousLayoutType, previousPresentationAreaContentActions, layoutContextDispatch, + isPresentationEnabled, ) => { const { layoutType } = layoutContextState; const { sidebarContent } = layoutContextState.input; @@ -1346,28 +1354,32 @@ const updatePresentationAreaContent = ( if (!equals( currentPresentationAreaContentActions, previousPresentationAreaContentActions.current, - )) { + ) || layoutType !== previousLayoutType) { + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id; + // eslint-disable-next-line no-param-reassign previousPresentationAreaContentActions.current = currentPresentationAreaContentActions.slice(0); const lastIndex = currentPresentationAreaContentActions.length - 1; const lastPresentationContentInPile = currentPresentationAreaContentActions[lastIndex]; + let shouldOpenPresentation = true; switch (lastPresentationContentInPile.value.content) { - case PRESENTATION_AREA.GENERIC_COMPONENT: { + case PRESENTATION_AREA.GENERIC_CONTENT: { layoutContextDispatch({ type: ACTIONS.SET_NOTES_IS_PINNED, value: !lastPresentationContentInPile.value.open, }); layoutContextDispatch({ - type: ACTIONS.SET_HAS_GENERIC_COMPONENT, - value: lastPresentationContentInPile.value.genericComponentId, + type: ACTIONS.SET_HAS_GENERIC_CONTENT, + value: lastPresentationContentInPile.value.genericContentId, }); break; } case PRESENTATION_AREA.PINNED_NOTES: { if ( - (sidebarContent.isOpen || !isPresentationEnabled()) + (sidebarContent.isOpen || !isPresentationEnabled) && (sidebarContent.sidebarContentPanel === PANELS.SHARED_NOTES - || !isPresentationEnabled()) + || !isPresentationEnabled) ) { if (layoutType === LAYOUT_TYPE.VIDEO_FOCUS) { layoutContextDispatch({ @@ -1391,7 +1403,7 @@ const updatePresentationAreaContent = ( } layoutContextDispatch({ - type: ACTIONS.SET_HAS_GENERIC_COMPONENT, + type: ACTIONS.SET_HAS_GENERIC_CONTENT, value: undefined, }); layoutContextDispatch({ @@ -1402,7 +1414,7 @@ const updatePresentationAreaContent = ( } case PRESENTATION_AREA.EXTERNAL_VIDEO: { layoutContextDispatch({ - type: ACTIONS.SET_HAS_GENERIC_COMPONENT, + type: ACTIONS.SET_HAS_GENERIC_CONTENT, value: undefined, }); layoutContextDispatch({ @@ -1417,7 +1429,7 @@ const updatePresentationAreaContent = ( } case PRESENTATION_AREA.SCREEN_SHARE: { layoutContextDispatch({ - type: ACTIONS.SET_HAS_GENERIC_COMPONENT, + type: ACTIONS.SET_HAS_GENERIC_CONTENT, value: undefined, }); layoutContextDispatch({ @@ -1440,13 +1452,14 @@ const updatePresentationAreaContent = ( value: !lastPresentationContentInPile.value.open, }); layoutContextDispatch({ - type: ACTIONS.SET_HAS_GENERIC_COMPONENT, + type: ACTIONS.SET_HAS_GENERIC_CONTENT, value: undefined, }); layoutContextDispatch({ type: ACTIONS.PINNED_NOTES, value: !lastPresentationContentInPile.value.open, }); + shouldOpenPresentation = Session.getItem('presentationLastState'); break; } default: @@ -1454,7 +1467,7 @@ const updatePresentationAreaContent = ( } layoutContextDispatch({ type: ACTIONS.SET_PRESENTATION_IS_OPEN, - value: true, + value: shouldOpenPresentation, }); } }; @@ -1469,17 +1482,23 @@ const LayoutContextProvider = (props) => { }, }], ); - const { data: pinnedPadData } = useSubscription(PINNED_PAD_SUBSCRIPTION); + const { data: pinnedPadData } = useDeduplicatedSubscription(PINNED_PAD_SUBSCRIPTION); const [layoutContextState, layoutContextDispatch] = useReducer(reducer, initState); + const isPresentationEnabled = useIsPresentationEnabled(); const { children } = props; + const { layoutType } = layoutContextState; + const previousLayoutType = usePrevious(layoutType); + useEffect(() => { updatePresentationAreaContent( layoutContextState, + previousLayoutType, previousPresentationAreaContentActions, layoutContextDispatch, + isPresentationEnabled, ); - }, [layoutContextState]); + }, [layoutContextState, isPresentationEnabled]); useEffect(() => { const isSharedNotesPinned = !!pinnedPadData && pinnedPadData.sharedNotes[0]?.pinned; diff --git a/bigbluebutton-html5/imports/ui/components/layout/defaultValues.js b/bigbluebutton-html5/imports/ui/components/layout/defaultValues.js index 6e96bfd6c1..bdace66e43 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/defaultValues.js +++ b/bigbluebutton-html5/imports/ui/components/layout/defaultValues.js @@ -1,13 +1,8 @@ -import { Meteor } from 'meteor/meteor'; import { LAYOUT_TYPE, CAMERADOCK_POSITION, PANELS } from './enums'; -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id; - const DEFAULT_VALUES = { layoutType: LAYOUT_TYPE.CUSTOM_LAYOUT, panelType: 'chat', - idChatOpen: PUBLIC_CHAT_ID, fontSize: 16, cameraPosition: CAMERADOCK_POSITION.CONTENT_TOP, diff --git a/bigbluebutton-html5/imports/ui/components/layout/enums.js b/bigbluebutton-html5/imports/ui/components/layout/enums.js index 0763ad15f9..58a701eea9 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/enums.js +++ b/bigbluebutton-html5/imports/ui/components/layout/enums.js @@ -107,8 +107,8 @@ export const ACTIONS = { SET_EXTERNAL_VIDEO_SIZE: 'setExternalVideoSize', SET_EXTERNAL_VIDEO_OUTPUT: 'setExternalVideoOutput', - SET_HAS_GENERIC_COMPONENT: 'setHasGenericComponent', - SET_GENERIC_COMPONENT_OUTPUT: 'setGenericComponentOutput', + SET_HAS_GENERIC_CONTENT: 'setHasGenericContent', + SET_GENERIC_CONTENT_OUTPUT: 'setGenericContentOutput', SET_SHARED_NOTES_OUTPUT: 'setSharedNotesOutput', SET_NOTES_IS_PINNED: 'setNotesIsPinned', @@ -117,7 +117,7 @@ export const ACTIONS = { }; export const PRESENTATION_AREA = { - GENERIC_COMPONENT: 'genericComponent', + GENERIC_CONTENT: 'genericContent', PINNED_NOTES: 'pinnedNotes', EXTERNAL_VIDEO: 'externalVideo', SCREEN_SHARE: 'screenShare', @@ -133,5 +133,6 @@ export const PANELS = { SHARED_NOTES: 'shared-notes', TIMER: 'timer', WAITING_USERS: 'waiting-users', + GENERIC_CONTENT_SIDEKICK: 'generic-content-sidekick', NONE: 'none', }; diff --git a/bigbluebutton-html5/imports/ui/components/layout/initState.js b/bigbluebutton-html5/imports/ui/components/layout/initState.js index 9f80b2e32b..b86e19aaf5 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/initState.js +++ b/bigbluebutton-html5/imports/ui/components/layout/initState.js @@ -2,7 +2,7 @@ import DEFAULT_VALUES from '/imports/ui/components/layout/defaultValues'; export const INITIAL_INPUT_STATE = { autoarrAngeLayout: true, - customParameters: { + userMetadata: { }, browser: { @@ -95,8 +95,8 @@ export const INITIAL_INPUT_STATE = { browserWidth: 0, browserHeight: 0, }, - genericComponent: { - genericComponentId: undefined, + genericMainContent: { + genericContentId: undefined, width: 0, height: 0, browserWidth: 0, @@ -241,7 +241,7 @@ export const INITIAL_OUTPUT_STATE = { tabOrder: 0, zIndex: 1, }, - genericComponent: { + genericMainContent: { display: false, width: 0, height: 0, diff --git a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/camerasOnly.jsx b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/camerasOnly.jsx index c8d2b76683..9e71c7de98 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/camerasOnly.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/camerasOnly.jsx @@ -7,8 +7,10 @@ import { } from '/imports/ui/components/layout/context'; import DEFAULT_VALUES from '/imports/ui/components/layout/defaultValues'; import { INITIAL_INPUT_STATE } from '/imports/ui/components/layout/initState'; -import { ACTIONS } from '/imports/ui/components/layout/enums'; +import { ACTIONS, PANELS } from '/imports/ui/components/layout/enums'; import { defaultsDeep } from '/imports/utils/array-utils'; +import Session from '/imports/ui/services/storage/in-memory'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const CamerasOnlyLayout = (props) => { const { bannerAreaHeight, isMobile, calculatesNavbarHeight } = props; @@ -23,11 +25,11 @@ const CamerasOnlyLayout = (props) => { const input = layoutSelect((i) => i.input); const deviceType = layoutSelect((i) => i.deviceType); - const isRTL = layoutSelect((i) => i.isRTL); + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application; const fullscreen = layoutSelect((i) => i.fullscreen); const fontSize = layoutSelect((i) => i.fontSize); const currentPanelType = layoutSelect((i) => i.currentPanelType); - const cameraDockInput = layoutSelectInput((i) => i.cameraDock); const navbarInput = layoutSelectInput((i) => i.navBar); const actionbarInput = layoutSelectInput((i) => i.actionBar); const layoutContextDispatch = layoutDispatch(); @@ -110,7 +112,6 @@ const CamerasOnlyLayout = (props) => { sidebarNavWidth.width, sidebarContentWidth.width, ); - console.log({mediaAreaBounds}) const navbarBounds = calculatesNavbarBounds(mediaAreaBounds); const actionbarBounds = calculatesActionbarBounds(mediaAreaBounds); const sidebarSize = sidebarContentWidth.width + sidebarNavWidth.width; @@ -297,7 +298,7 @@ const CamerasOnlyLayout = (props) => { }); layoutContextDispatch({ - type: ACTIONS.SET_GENERIC_COMPONENT_OUTPUT, + type: ACTIONS.SET_GENERIC_CONTENT_OUTPUT, value: { display: false, width: mediaBounds.width, @@ -319,6 +320,21 @@ const CamerasOnlyLayout = (props) => { right: isRTL ? mediaBounds.right : null, }, }); + + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_NAVIGATION_IS_OPEN, + value: false, + }); + + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, + value: false, + }); + + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, + value: PANELS.NONE, + }); }; const throttledCalculatesLayout = throttle(() => calculatesLayout(), 50, { @@ -341,41 +357,44 @@ const CamerasOnlyLayout = (props) => { const init = () => { layoutContextDispatch({ type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( - { - sidebarNavigation: { - isOpen: false, - width: 0, - height: 0, + value: (prevInput) => { + const { cameraDock } = prevInput; + return defaultsDeep( + { + sidebarNavigation: { + isOpen: false, + width: 0, + height: 0, + }, + sidebarContent: { + isOpen: false, + width: 0, + height: 0, + }, + SidebarContentHorizontalResizer: { + isOpen: false, + }, + presentation: { + isOpen: false, + }, + cameraDock: { + numCameras: cameraDock.numCameras, + }, + externalVideo: { + hasExternalVideo: false, + }, + genericMainContent: { + genericContentId: undefined, + }, + screenShare: { + hasScreenShare: false, + }, }, - sidebarContent: { - isOpen: false, - width: 0, - height: 0, - }, - SidebarContentHorizontalResizer: { - isOpen: false, - }, - presentation: { - isOpen: false, - }, - cameraDock: { - numCameras: cameraDockInput.numCameras, - }, - externalVideo: { - hasExternalVideo: false, - }, - genericComponent: { - genericComponentId: undefined, - }, - screenShare: { - hasScreenShare: false, - }, - }, - INITIAL_INPUT_STATE, - ), + INITIAL_INPUT_STATE, + ); + }, }); - Session.set('layoutReady', true); + Session.setItem('layoutReady', true); throttledCalculatesLayout(); }; diff --git a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/customLayout.jsx b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/customLayout.jsx index daa406a6a7..a67f9f925a 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/customLayout.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/customLayout.jsx @@ -6,7 +6,8 @@ import { INITIAL_INPUT_STATE } from '/imports/ui/components/layout/initState'; import { ACTIONS, CAMERADOCK_POSITION, PANELS } from '../enums'; import Storage from '/imports/ui/services/storage/session'; import { defaultsDeep } from '/imports/utils/array-utils'; -import { isPresentationEnabled } from '/imports/ui/services/features'; +import Session from '/imports/ui/services/storage/in-memory'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const windowWidth = () => window.document.documentElement.clientWidth; const windowHeight = () => window.document.documentElement.clientHeight; @@ -26,14 +27,15 @@ const CustomLayout = (props) => { const input = layoutSelect((i) => i.input); const deviceType = layoutSelect((i) => i.deviceType); - const isRTL = layoutSelect((i) => i.isRTL); + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application; const fullscreen = layoutSelect((i) => i.fullscreen); const fontSize = layoutSelect((i) => i.fontSize); const currentPanelType = layoutSelect((i) => i.currentPanelType); const presentationInput = layoutSelectInput((i) => i.presentation); const externalVideoInput = layoutSelectInput((i) => i.externalVideo); - const genericComponentInput = layoutSelectInput((i) => i.genericComponent); + const genericMainContentInput = layoutSelectInput((i) => i.genericMainContent); const screenShareInput = layoutSelectInput((i) => i.screenShare); const sharedNotesInput = layoutSelectInput((i) => i.sharedNotes); @@ -48,6 +50,7 @@ const CustomLayout = (props) => { const prevDeviceType = usePrevious(deviceType); const prevIsResizing = usePrevious(isResizing); + const { isPresentationEnabled } = props; const throttledCalculatesLayout = throttle(() => calculatesLayout(), 50, { trailing: true, leading: true }); @@ -74,7 +77,7 @@ const CustomLayout = (props) => { } else { throttledCalculatesLayout(); } - }, [input, deviceType, isRTL, fontSize, fullscreen]); + }, [input, deviceType, isRTL, fontSize, fullscreen, isPresentationEnabled]); const calculatesDropAreas = (sidebarNavWidth, sidebarContentWidth, cameraDockBounds) => { const { height: actionBarHeight } = calculatesActionbarHeight(); @@ -132,112 +135,124 @@ const CustomLayout = (props) => { }; const init = () => { - const { sidebarContentPanel } = sidebarContentInput; - if (isMobile) { layoutContextDispatch({ type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( - { - sidebarNavigation: { - isOpen: - input.sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, - sidebarNavPanel: sidebarNavigationInput.sidebarNavPanel, - }, - sidebarContent: { - isOpen: sidebarContentPanel !== PANELS.NONE, - sidebarContentPanel: sidebarContentInput.sidebarContentPanel, - }, - sidebarContentHorizontalResizer: { - isOpen: false, - }, - presentation: { - isOpen: presentationInput.isOpen, - slidesLength: presentationInput.slidesLength, - currentSlide: { - ...presentationInput.currentSlide, + value: (prevInput) => { + const { + sidebarNavigation, sidebarContent, presentation, cameraDock, + externalVideo, genericMainContent, screenShare, sharedNotes, + } = prevInput; + const { sidebarContentPanel } = sidebarContent; + return defaultsDeep( + { + sidebarNavigation: { + isOpen: + sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, + sidebarNavPanel: sidebarNavigation.sidebarNavPanel, + }, + sidebarContent: { + isOpen: sidebarContentPanel !== PANELS.NONE, + sidebarContentPanel: sidebarContent.sidebarContentPanel, + }, + sidebarContentHorizontalResizer: { + isOpen: false, + }, + presentation: { + isOpen: presentation.isOpen, + slidesLength: presentation.slidesLength, + currentSlide: { + ...presentation.currentSlide, + }, + }, + cameraDock: { + numCameras: cameraDock.numCameras, + }, + externalVideo: { + hasExternalVideo: externalVideo.hasExternalVideo, + }, + genericMainContent: { + genericContentId: genericMainContent.genericContentId, + }, + screenShare: { + hasScreenShare: screenShare.hasScreenShare, + width: screenShare.width, + height: screenShare.height, + }, + sharedNotes: { + isPinned: sharedNotes.isPinned, }, }, - cameraDock: { - numCameras: cameraDockInput.numCameras, - }, - externalVideo: { - hasExternalVideo: input.externalVideo.hasExternalVideo, - }, - genericComponent: { - genericComponentId: input.genericComponent.genericComponentId, - }, - screenShare: { - hasScreenShare: input.screenShare.hasScreenShare, - width: input.screenShare.width, - height: input.screenShare.height, - }, - sharedNotes: { - isPinned: sharedNotesInput.isPinned, - }, - }, - INITIAL_INPUT_STATE - ), + INITIAL_INPUT_STATE, + ); + }, }); } else { layoutContextDispatch({ type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( - { - sidebarNavigation: { - isOpen: - input.sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, - }, - sidebarContent: { - isOpen: sidebarContentPanel !== PANELS.NONE, - sidebarContentPanel, - }, - sidebarContentHorizontalResizer: { - isOpen: false, - }, - presentation: { - isOpen: presentationInput.isOpen, - slidesLength: presentationInput.slidesLength, - currentSlide: { - ...presentationInput.currentSlide, + value: (prevInput) => { + const { + sidebarNavigation, sidebarContent, presentation, cameraDock, + externalVideo, genericMainContent, screenShare, sharedNotes, + } = prevInput; + const { sidebarContentPanel } = sidebarContent; + return defaultsDeep( + { + sidebarNavigation: { + isOpen: + sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, + }, + sidebarContent: { + isOpen: sidebarContentPanel !== PANELS.NONE, + sidebarContentPanel, + }, + sidebarContentHorizontalResizer: { + isOpen: false, + }, + presentation: { + isOpen: presentation.isOpen, + slidesLength: presentation.slidesLength, + currentSlide: { + ...presentation.currentSlide, + }, + }, + cameraDock: { + numCameras: cameraDock.numCameras, + }, + externalVideo: { + hasExternalVideo: externalVideo.hasExternalVideo, + }, + genericMainContent: { + genericContentId: genericMainContent.genericContentId, + }, + screenShare: { + hasScreenShare: screenShare.hasScreenShare, + width: screenShare.width, + height: screenShare.height, + }, + sharedNotes: { + isPinned: sharedNotes.isPinned, }, }, - cameraDock: { - numCameras: cameraDockInput.numCameras, - }, - externalVideo: { - hasExternalVideo: input.externalVideo.hasExternalVideo, - }, - genericComponent: { - genericComponentId: input.genericComponent.genericComponentId, - }, - screenShare: { - hasScreenShare: input.screenShare.hasScreenShare, - width: input.screenShare.width, - height: input.screenShare.height, - }, - sharedNotes: { - isPinned: sharedNotesInput.isPinned, - }, - }, - INITIAL_INPUT_STATE - ), + INITIAL_INPUT_STATE, + ); + }, }); } - Session.set('layoutReady', true); + Session.setItem('layoutReady', true); throttledCalculatesLayout(); }; const calculatesSidebarContentHeight = (cameraDockHeight) => { const { isOpen, slidesLength } = presentationInput; const { hasExternalVideo } = externalVideoInput; - const { genericComponentId } = genericComponentInput; + const { genericContentId } = genericMainContentInput; const { hasScreenShare } = screenShareInput; const { isPinned: isSharedNotesPinned } = sharedNotesInput; - const hasPresentation = isPresentationEnabled() && slidesLength !== 0; + const hasPresentation = isPresentationEnabled && slidesLength !== 0; const isGeneralMediaOff = !hasPresentation && !hasExternalVideo - && !hasScreenShare && !isSharedNotesPinned && !genericComponentId; + && !hasScreenShare && !isSharedNotesPinned && !genericContentId; let sidebarContentHeight = 0; if (sidebarContentInput.isOpen) { @@ -409,7 +424,7 @@ const CustomLayout = (props) => { const calculatesMediaBounds = (sidebarNavWidth, sidebarContentWidth, cameraDockBounds) => { const { isOpen, slidesLength } = presentationInput; const { hasExternalVideo } = externalVideoInput; - const { genericComponentId } = genericComponentInput; + const { genericContentId } = genericMainContentInput; const { hasScreenShare } = screenShareInput; const { isPinned: isSharedNotesPinned } = sharedNotesInput; @@ -422,9 +437,9 @@ const CustomLayout = (props) => { const { element: fullscreenElement } = fullscreen; const { camerasMargin } = DEFAULT_VALUES; - const hasPresentation = isPresentationEnabled() && slidesLength !== 0; + const hasPresentation = isPresentationEnabled && slidesLength !== 0; const isGeneralMediaOff = !hasPresentation && !hasExternalVideo - && !hasScreenShare && !isSharedNotesPinned && !genericComponentId; + && !hasScreenShare && !isSharedNotesPinned && !genericContentId; if (!isOpen || isGeneralMediaOff) { mediaBounds.width = 0; @@ -440,7 +455,7 @@ const CustomLayout = (props) => { fullscreenElement === 'Presentation' || fullscreenElement === 'Screenshare' || fullscreenElement === 'ExternalVideo' || - fullscreenElement === 'GenericComponent' + fullscreenElement === 'GenericContent' ) { mediaBounds.width = windowWidth(); mediaBounds.height = windowHeight(); @@ -748,7 +763,7 @@ const CustomLayout = (props) => { }); layoutContextDispatch({ - type: ACTIONS.SET_GENERIC_COMPONENT_OUTPUT, + type: ACTIONS.SET_GENERIC_CONTENT_OUTPUT, value: { width: mediaBounds.width, height: mediaBounds.height, diff --git a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/layoutEngine.jsx b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/layoutEngine.jsx index afa0ef8eb6..a7114b6a37 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/layoutEngine.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/layoutEngine.jsx @@ -11,13 +11,14 @@ import VideoFocusLayout from '/imports/ui/components/layout/layout-manager/video import CamerasOnlyLayout from '/imports/ui/components/layout/layout-manager/camerasOnly'; import PresentationOnlyLayout from '/imports/ui/components/layout/layout-manager/presentationOnlyLayout'; import ParticipantsAndChatOnlyLayout from '/imports/ui/components/layout/layout-manager/participantsAndChatOnlyLayout'; -import { isPresentationEnabled } from '/imports/ui/services/features'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const propTypes = { layoutType: PropTypes.string.isRequired, + isPresentationEnabled: PropTypes.bool.isRequired, }; -const LayoutEngine = ({ layoutType }) => { +const LayoutEngine = ({ layoutType, isPresentationEnabled }) => { const bannerBarInput = layoutSelectInput((i) => i.bannerBar); const notificationsBarInput = layoutSelectInput((i) => i.notificationsBar); const cameraDockInput = layoutSelectInput((i) => i.cameraDock); @@ -27,12 +28,13 @@ const LayoutEngine = ({ layoutType }) => { const sidebarNavigationInput = layoutSelectInput((i) => i.sidebarNavigation); const sidebarContentInput = layoutSelectInput((i) => i.sidebarContent); const externalVideoInput = layoutSelectInput((i) => i.externalVideo); - const genericComponentInput = layoutSelectInput((i) => i.genericComponent); + const genericMainContentInput = layoutSelectInput((i) => i.genericMainContent); const screenShareInput = layoutSelectInput((i) => i.screenShare); const sharedNotesInput = layoutSelectInput((i) => i.sharedNotes); const fullscreen = layoutSelect((i) => i.fullscreen); - const isRTL = layoutSelect((i) => i.isRTL); + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application; const fontSize = layoutSelect((i) => i.fontSize); const deviceType = layoutSelect((i) => i.deviceType); @@ -55,7 +57,7 @@ const LayoutEngine = ({ layoutType }) => { const baseCameraDockBounds = (mediaAreaBounds, sidebarSize) => { const { isOpen, slidesLength } = presentationInput; const { hasExternalVideo } = externalVideoInput; - const { genericComponentId } = genericComponentInput; + const { genericContentId } = genericMainContentInput; const { hasScreenShare } = screenShareInput; const { isPinned: isSharedNotesPinned } = sharedNotesInput; @@ -69,10 +71,10 @@ const LayoutEngine = ({ layoutType }) => { } const navBarHeight = calculatesNavbarHeight(); - const hasPresentation = isPresentationEnabled() && slidesLength !== 0; + const hasPresentation = isPresentationEnabled && slidesLength !== 0; const isGeneralMediaOff = !hasPresentation && !hasExternalVideo && !hasScreenShare - && !isSharedNotesPinned && !genericComponentId; + && !isSharedNotesPinned && !genericContentId; if (!isOpen || isGeneralMediaOff) { cameraDockBounds.width = mediaAreaBounds.width; @@ -335,16 +337,16 @@ const LayoutEngine = ({ layoutType }) => { switch (layoutType) { case LAYOUT_TYPE.CUSTOM_LAYOUT: layout?.setAttribute('data-layout', LAYOUT_TYPE.CUSTOM_LAYOUT); - return ; + return ; case LAYOUT_TYPE.SMART_LAYOUT: layout?.setAttribute('data-layout', LAYOUT_TYPE.SMART_LAYOUT); - return ; + return ; case LAYOUT_TYPE.PRESENTATION_FOCUS: layout?.setAttribute('data-layout', LAYOUT_TYPE.PRESENTATION_FOCUS); - return ; + return ; case LAYOUT_TYPE.VIDEO_FOCUS: layout?.setAttribute('data-layout', LAYOUT_TYPE.VIDEO_FOCUS); - return ; + return ; case LAYOUT_TYPE.CAMERAS_ONLY: layout?.setAttribute('data-layout', LAYOUT_TYPE.CAMERAS_ONLY); return ; @@ -356,7 +358,7 @@ const LayoutEngine = ({ layoutType }) => { return ; default: layout?.setAttribute('data-layout', LAYOUT_TYPE.CUSTOM_LAYOUT); - return ; + return ; } }; diff --git a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/participantsAndChatOnlyLayout.jsx b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/participantsAndChatOnlyLayout.jsx index 89f2303104..2ca3373324 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/participantsAndChatOnlyLayout.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/participantsAndChatOnlyLayout.jsx @@ -9,6 +9,8 @@ import { CAMERADOCK_POSITION, } from '/imports/ui/components/layout/enums'; import { defaultsDeep } from '/imports/utils/array-utils'; +import Session from '/imports/ui/services/storage/in-memory'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const windowWidth = () => window.document.documentElement.clientWidth; const windowHeight = () => window.document.documentElement.clientHeight; @@ -26,7 +28,8 @@ const ParticipantsAndChatOnlyLayout = (props) => { const input = layoutSelect((i) => i.input); const deviceType = layoutSelect((i) => i.deviceType); - const isRTL = layoutSelect((i) => i.isRTL); + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application; const fullscreen = layoutSelect((i) => i.fullscreen); const fontSize = layoutSelect((i) => i.fontSize); const currentPanelType = layoutSelect((i) => i.currentPanelType); @@ -111,7 +114,7 @@ const ParticipantsAndChatOnlyLayout = (props) => { fullscreenElement === 'Presentation' || fullscreenElement === 'Screenshare' || fullscreenElement === 'ExternalVideo' - || fullscreenElement === 'GenericComponent' + || fullscreenElement === 'GenericContent' ) { mediaBounds.width = windowWidth(); mediaBounds.height = windowHeight(); @@ -336,7 +339,7 @@ const ParticipantsAndChatOnlyLayout = (props) => { }); layoutContextDispatch({ - type: ACTIONS.SET_GENERIC_COMPONENT_OUTPUT, + type: ACTIONS.SET_GENERIC_CONTENT_OUTPUT, value: { display: false, width: 0, @@ -376,54 +379,57 @@ const ParticipantsAndChatOnlyLayout = (props) => { }, []); const init = () => { - const { sidebarContentPanel } = sidebarContentInput; layoutContextDispatch({ type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( - { - sidebarNavigation: { - isOpen: - input.sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, - }, - sidebarContent: { - isOpen: sidebarContentPanel !== PANELS.NONE, - sidebarContentPanel, - }, - SidebarContentHorizontalResizer: { - isOpen: false, - }, - presentation: { - isOpen: false, - slidesLength: presentationInput.slidesLength, - currentSlide: { - ...presentationInput.currentSlide, + value: (prevInput) => { + const { sidebarNavigation, sidebarContent, presentation } = prevInput; + const { sidebarContentPanel } = sidebarContent; + return defaultsDeep( + { + sidebarNavigation: { + isOpen: + sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, + }, + sidebarContent: { + isOpen: sidebarContentPanel !== PANELS.NONE, + sidebarContentPanel, + }, + SidebarContentHorizontalResizer: { + isOpen: false, + }, + presentation: { + isOpen: false, + slidesLength: presentation.slidesLength, + currentSlide: { + ...presentation.currentSlide, + }, + width: 0, + height: 0, + }, + cameraDock: { + numCameras: 0, + }, + externalVideo: { + hasExternalVideo: false, + width: 0, + height: 0, + }, + genericMainContent: { + genericContentId: undefined, + width: 0, + height: 0, + }, + screenShare: { + hasScreenShare: false, + width: 0, + height: 0, }, - width: 0, - height: 0, }, - cameraDock: { - numCameras: 0, - }, - externalVideo: { - hasExternalVideo: false, - width: 0, - height: 0, - }, - genericComponent: { - genericComponentId: undefined, - width: 0, - height: 0, - }, - screenShare: { - hasScreenShare: false, - width: 0, - height: 0, - }, - }, - INITIAL_INPUT_STATE, - ), + INITIAL_INPUT_STATE, + ); + }, }); - Session.set('layoutReady', true); + Session.setItem('layoutReady', true); throttledCalculatesLayout(); }; diff --git a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/presentationFocusLayout.jsx b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/presentationFocusLayout.jsx index 309be79a9e..4542e2c0cd 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/presentationFocusLayout.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/presentationFocusLayout.jsx @@ -9,7 +9,8 @@ import { CAMERADOCK_POSITION, } from '/imports/ui/components/layout/enums'; import { defaultsDeep } from '/imports/utils/array-utils'; -import { isPresentationEnabled } from '/imports/ui/services/features'; +import Session from '/imports/ui/services/storage/in-memory'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const windowWidth = () => window.document.documentElement.clientWidth; const windowHeight = () => window.document.documentElement.clientHeight; @@ -29,14 +30,15 @@ const PresentationFocusLayout = (props) => { const input = layoutSelect((i) => i.input); const deviceType = layoutSelect((i) => i.deviceType); - const isRTL = layoutSelect((i) => i.isRTL); + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application const fullscreen = layoutSelect((i) => i.fullscreen); const fontSize = layoutSelect((i) => i.fontSize); const currentPanelType = layoutSelect((i) => i.currentPanelType); const presentationInput = layoutSelectInput((i) => i.presentation); const externalVideoInput = layoutSelectInput((i) => i.externalVideo); - const genericComponentInput = layoutSelectInput((i) => i.genericComponent); + const genericMainContentInput = layoutSelectInput((i) => i.genericMainContent); const screenShareInput = layoutSelectInput((i) => i.screenShare); const sharedNotesInput = layoutSelectInput((i) => i.sharedNotes); @@ -48,6 +50,7 @@ const PresentationFocusLayout = (props) => { const layoutContextDispatch = layoutDispatch(); const prevDeviceType = usePrevious(deviceType); + const { isPresentationEnabled } = props; const throttledCalculatesLayout = throttle(() => calculatesLayout(), 50, { trailing: true, leading: true }); @@ -74,18 +77,22 @@ const PresentationFocusLayout = (props) => { } else { throttledCalculatesLayout(); } - }, [input, deviceType, isRTL, fontSize, fullscreen]); + }, [input, deviceType, isRTL, fontSize, fullscreen, isPresentationEnabled]); const init = () => { - const { sidebarContentPanel } = sidebarContentInput; - if (isMobile) { - layoutContextDispatch({ - type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( + layoutContextDispatch({ + type: ACTIONS.SET_LAYOUT_INPUT, + value: (prevInput) => { + const { + sidebarNavigation, sidebarContent, presentation, cameraDock, + externalVideo, genericMainContent, screenShare, + } = prevInput; + const { sidebarContentPanel } = sidebarContent; + return defaultsDeep( { sidebarNavigation: { isOpen: - input.sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, + sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, }, sidebarContent: { isOpen: sidebarContentPanel !== PANELS.NONE, @@ -95,86 +102,45 @@ const PresentationFocusLayout = (props) => { isOpen: false, }, presentation: { - isOpen: presentationInput.isOpen, - slidesLength: presentationInput.slidesLength, + isOpen: presentation.isOpen, + slidesLength: presentation.slidesLength, currentSlide: { - ...presentationInput.currentSlide, + ...presentation.currentSlide, }, }, cameraDock: { - numCameras: cameraDockInput.numCameras, + numCameras: cameraDock.numCameras, }, externalVideo: { - hasExternalVideo: input.externalVideo.hasExternalVideo, + hasExternalVideo: externalVideo.hasExternalVideo, }, - genericComponent: { - genericComponentId: input.genericComponent.genericComponentId, + genericMainContent: { + genericContentId: genericMainContent.genericContentId, }, screenShare: { - hasScreenShare: input.screenShare.hasScreenShare, - width: input.screenShare.width, - height: input.screenShare.height, + hasScreenShare: screenShare.hasScreenShare, + width: screenShare.width, + height: screenShare.height, }, }, - INITIAL_INPUT_STATE - ), - }); - } else { - layoutContextDispatch({ - type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( - { - sidebarNavigation: { - isOpen: - input.sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, - }, - sidebarContent: { - isOpen: sidebarContentPanel !== PANELS.NONE, - sidebarContentPanel, - }, - SidebarContentHorizontalResizer: { - isOpen: false, - }, - presentation: { - isOpen: presentationInput.isOpen, - slidesLength: presentationInput.slidesLength, - currentSlide: { - ...presentationInput.currentSlide, - }, - }, - cameraDock: { - numCameras: cameraDockInput.numCameras, - }, - externalVideo: { - hasExternalVideo: input.externalVideo.hasExternalVideo, - }, - genericComponent: { - genericComponentId: input.genericComponent.genericComponentId, - }, - screenShare: { - hasScreenShare: input.screenShare.hasScreenShare, - width: input.screenShare.width, - height: input.screenShare.height, - }, - }, - INITIAL_INPUT_STATE - ), - }); - } - Session.set('layoutReady', true); + INITIAL_INPUT_STATE, + ); + }, + }); + Session.setItem('layoutReady', true); throttledCalculatesLayout(); }; const calculatesSidebarContentHeight = () => { const { isOpen, slidesLength } = presentationInput; const { hasExternalVideo } = externalVideoInput; - const { genericComponentId } = genericComponentInput; + const { genericContentId } = genericMainContentInput; const { hasScreenShare } = screenShareInput; const { isPinned: isSharedNotesPinned } = sharedNotesInput; - const hasPresentation = isPresentationEnabled() && slidesLength !== 0; + const hasPresentation = isPresentationEnabled && slidesLength !== 0; const isGeneralMediaOff = !hasPresentation && !hasExternalVideo - && !hasScreenShare && !isSharedNotesPinned && !genericComponentId; + && !hasScreenShare && !isSharedNotesPinned && !genericContentId; const { navBarHeight, sidebarContentMinHeight } = DEFAULT_VALUES; let height = 0; @@ -276,7 +242,7 @@ const PresentationFocusLayout = (props) => { fullscreenElement === 'Presentation' || fullscreenElement === 'Screenshare' || fullscreenElement === 'ExternalVideo' || - fullscreenElement === 'GenericComponent' + fullscreenElement === 'GenericContent' ) { mediaBounds.width = windowWidth(); mediaBounds.height = windowHeight(); @@ -506,7 +472,7 @@ const PresentationFocusLayout = (props) => { }); layoutContextDispatch({ - type: ACTIONS.SET_GENERIC_COMPONENT_OUTPUT, + type: ACTIONS.SET_GENERIC_CONTENT_OUTPUT, value: { width: isOpen ? mediaBounds.width : 0, height: isOpen ? mediaBounds.height : 0, diff --git a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/presentationOnlyLayout.jsx b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/presentationOnlyLayout.jsx index c0bdba1e24..36af5e4339 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/presentationOnlyLayout.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/presentationOnlyLayout.jsx @@ -5,9 +5,12 @@ import DEFAULT_VALUES from '/imports/ui/components/layout/defaultValues'; import { INITIAL_INPUT_STATE } from '/imports/ui/components/layout/initState'; import { ACTIONS, + PANELS, CAMERADOCK_POSITION, } from '/imports/ui/components/layout/enums'; import { defaultsDeep } from '/imports/utils/array-utils'; +import Session from '/imports/ui/services/storage/in-memory'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const windowWidth = () => window.document.documentElement.clientWidth; const windowHeight = () => window.document.documentElement.clientHeight; @@ -25,7 +28,8 @@ const PresentationOnlyLayout = (props) => { const input = layoutSelect((i) => i.input); const deviceType = layoutSelect((i) => i.deviceType); - const isRTL = layoutSelect((i) => i.isRTL); + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application; const fullscreen = layoutSelect((i) => i.fullscreen); const fontSize = layoutSelect((i) => i.fontSize); const currentPanelType = layoutSelect((i) => i.currentPanelType); @@ -47,7 +51,7 @@ const PresentationOnlyLayout = (props) => { fullscreenElement === 'Presentation' || fullscreenElement === 'Screenshare' || fullscreenElement === 'ExternalVideo' - || fullscreenElement === 'GenericComponent' + || fullscreenElement === 'GenericContent' ) { mediaBounds.width = windowWidth(); mediaBounds.height = windowHeight(); @@ -289,7 +293,7 @@ const PresentationOnlyLayout = (props) => { }); layoutContextDispatch({ - type: ACTIONS.SET_GENERIC_COMPONENT_OUTPUT, + type: ACTIONS.SET_GENERIC_CONTENT_OUTPUT, value: { width: isOpen ? mediaBounds.width : 0, height: isOpen ? mediaBounds.height : 0, @@ -309,6 +313,21 @@ const PresentationOnlyLayout = (props) => { right: mediaBounds.right, }, }); + + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_NAVIGATION_IS_OPEN, + value: false, + }); + + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, + value: false, + }); + + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, + value: PANELS.NONE, + }); }; const throttledCalculatesLayout = throttle(() => calculatesLayout(), @@ -329,47 +348,52 @@ const PresentationOnlyLayout = (props) => { const init = () => { layoutContextDispatch({ type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( - { - sidebarNavigation: { - isOpen: false, - width: 0, - height: 0, - }, - sidebarContent: { - isOpen: false, - width: 0, - height: 0, - }, - SidebarContentHorizontalResizer: { - isOpen: false, - }, - presentation: { - isOpen: true, - slidesLength: presentationInput.slidesLength, - currentSlide: { - ...presentationInput.currentSlide, + value: (prevInput) => { + const { + presentation, externalVideo, genericMainContent, screenShare, + } = prevInput; + return defaultsDeep( + { + sidebarNavigation: { + isOpen: false, + width: 0, + height: 0, + }, + sidebarContent: { + isOpen: false, + width: 0, + height: 0, + }, + SidebarContentHorizontalResizer: { + isOpen: false, + }, + presentation: { + isOpen: true, + slidesLength: presentation.slidesLength, + currentSlide: { + ...presentation.currentSlide, + }, + }, + cameraDock: { + numCameras: 0, + }, + externalVideo: { + hasExternalVideo: externalVideo.hasExternalVideo, + }, + genericMainContent: { + genericContentId: genericMainContent.genericContentId, + }, + screenShare: { + hasScreenShare: screenShare.hasScreenShare, + width: screenShare.width, + height: screenShare.height, }, }, - cameraDock: { - numCameras: 0, - }, - externalVideo: { - hasExternalVideo: input.externalVideo.hasExternalVideo, - }, - genericComponent: { - genericComponentId: input.genericComponent.genericComponentId, - }, - screenShare: { - hasScreenShare: input.screenShare.hasScreenShare, - width: input.screenShare.width, - height: input.screenShare.height, - }, - }, - INITIAL_INPUT_STATE, - ), + INITIAL_INPUT_STATE, + ); + }, }); - Session.set('layoutReady', true); + Session.setItem('layoutReady', true); throttledCalculatesLayout(); }; diff --git a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/smartLayout.jsx b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/smartLayout.jsx index 6e9910a40e..76b452b060 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/smartLayout.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/smartLayout.jsx @@ -5,7 +5,8 @@ import DEFAULT_VALUES from '/imports/ui/components/layout/defaultValues'; import { INITIAL_INPUT_STATE } from '/imports/ui/components/layout/initState'; import { ACTIONS, PANELS, CAMERADOCK_POSITION } from '/imports/ui/components/layout/enums'; import { defaultsDeep } from '/imports/utils/array-utils'; -import { isPresentationEnabled } from '/imports/ui/services/features'; +import Session from '/imports/ui/services/storage/in-memory'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const windowWidth = () => window.document.documentElement.clientWidth; const windowHeight = () => window.document.documentElement.clientHeight; @@ -23,7 +24,8 @@ const SmartLayout = (props) => { const input = layoutSelect((i) => i.input); const deviceType = layoutSelect((i) => i.deviceType); - const isRTL = layoutSelect((i) => i.isRTL); + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application; const fullscreen = layoutSelect((i) => i.fullscreen); const fontSize = layoutSelect((i) => i.fontSize); const currentPanelType = layoutSelect((i) => i.currentPanelType); @@ -35,12 +37,13 @@ const SmartLayout = (props) => { const actionbarInput = layoutSelectInput((i) => i.actionBar); const navbarInput = layoutSelectInput((i) => i.navBar); const externalVideoInput = layoutSelectInput((i) => i.externalVideo); - const genericComponentInput = layoutSelectInput((i) => i.genericComponent); + const genericMainContentInput = layoutSelectInput((i) => i.genericMainContent); const screenShareInput = layoutSelectInput((i) => i.screenShare); const sharedNotesInput = layoutSelectInput((i) => i.sharedNotes); const layoutContextDispatch = layoutDispatch(); const prevDeviceType = usePrevious(deviceType); + const { isPresentationEnabled } = props; const throttledCalculatesLayout = throttle(() => calculatesLayout(), 50, { trailing: true, @@ -69,19 +72,22 @@ const SmartLayout = (props) => { } else { throttledCalculatesLayout(); } - }, [input, deviceType, isRTL, fontSize, fullscreen]); + }, [input, deviceType, isRTL, fontSize, fullscreen, isPresentationEnabled]); const init = () => { - const { sidebarContentPanel } = sidebarContentInput; - - if (isMobile) { - layoutContextDispatch({ - type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( + layoutContextDispatch({ + type: ACTIONS.SET_LAYOUT_INPUT, + value: (prevInput) => { + const { + sidebarNavigation, sidebarContent, presentation, cameraDock, + externalVideo, genericMainContent, screenShare, sharedNotes, + } = prevInput; + const { sidebarContentPanel } = sidebarContent; + return defaultsDeep( { sidebarNavigation: { isOpen: - input.sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, + sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, }, sidebarContent: { isOpen: sidebarContentPanel !== PANELS.NONE, @@ -91,79 +97,35 @@ const SmartLayout = (props) => { isOpen: false, }, presentation: { - isOpen: presentationInput.isOpen, - slidesLength: presentationInput.slidesLength, + isOpen: presentation.isOpen, + slidesLength: presentation.slidesLength, currentSlide: { - ...presentationInput.currentSlide, + ...presentation.currentSlide, }, }, cameraDock: { - numCameras: cameraDockInput.numCameras, + numCameras: cameraDock.numCameras, }, externalVideo: { - hasExternalVideo: externalVideoInput.hasExternalVideo, + hasExternalVideo: externalVideo.hasExternalVideo, }, - genericComponent: { - genericComponentId: genericComponentInput.genericComponentId, + genericMainContent: { + genericContentId: genericMainContent.genericContentId, }, screenShare: { - hasScreenShare: screenShareInput.hasScreenShare, - width: screenShareInput.width, - height: screenShareInput.height, + hasScreenShare: screenShare.hasScreenShare, + width: screenShare.width, + height: screenShare.height, }, sharedNotes: { - isPinned: sharedNotesInput.isPinned, + isPinned: sharedNotes.isPinned, }, }, - INITIAL_INPUT_STATE - ), - }); - } else { - layoutContextDispatch({ - type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( - { - sidebarNavigation: { - isOpen: - input.sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, - }, - sidebarContent: { - isOpen: sidebarContentPanel !== PANELS.NONE, - sidebarContentPanel, - }, - SidebarContentHorizontalResizer: { - isOpen: false, - }, - presentation: { - isOpen: presentationInput.isOpen, - slidesLength: presentationInput.slidesLength, - currentSlide: { - ...presentationInput.currentSlide, - }, - }, - cameraDock: { - numCameras: cameraDockInput.numCameras, - }, - externalVideo: { - hasExternalVideo: externalVideoInput.hasExternalVideo, - }, - genericComponent: { - genericComponentId: genericComponentInput.genericComponentId, - }, - screenShare: { - hasScreenShare: screenShareInput.hasScreenShare, - width: screenShareInput.width, - height: screenShareInput.height, - }, - sharedNotes: { - isPinned: sharedNotesInput.isPinned, - }, - }, - INITIAL_INPUT_STATE - ), - }); - } - Session.set('layoutReady', true); + INITIAL_INPUT_STATE, + ); + }, + }); + Session.setItem('layoutReady', true); throttledCalculatesLayout(); }; @@ -288,13 +250,13 @@ const SmartLayout = (props) => { const calculatesMediaBounds = (mediaAreaBounds, slideSize, sidebarSize, screenShareSize) => { const { isOpen, slidesLength } = presentationInput; const { hasExternalVideo } = externalVideoInput; - const { genericComponentId } = genericComponentInput; + const { genericContentId } = genericMainContentInput; const { hasScreenShare } = screenShareInput; const { isPinned: isSharedNotesPinned } = sharedNotesInput; - const hasPresentation = isPresentationEnabled() && slidesLength !== 0; + const hasPresentation = isPresentationEnabled && slidesLength !== 0; const isGeneralMediaOff = !hasPresentation && !hasExternalVideo - && !hasScreenShare && !isSharedNotesPinned && !genericComponentId; + && !hasScreenShare && !isSharedNotesPinned && !genericContentId; const mediaBounds = {}; const { element: fullscreenElement } = fullscreen; @@ -313,7 +275,7 @@ const SmartLayout = (props) => { fullscreenElement === 'Presentation' || fullscreenElement === 'Screenshare' || fullscreenElement === 'ExternalVideo' || - fullscreenElement === 'GenericComponent' + fullscreenElement === 'GenericContent' ) { mediaBounds.width = windowWidth(); mediaBounds.height = windowHeight(); @@ -328,7 +290,7 @@ const SmartLayout = (props) => { if (cameraDockInput.numCameras > 0 && !cameraDockInput.isDragging) { if (mediaContentSize.width !== 0 && mediaContentSize.height !== 0 - && !hasExternalVideo && !genericComponentId) { + && !hasExternalVideo && !genericContentId) { if (mediaContentSize.width < mediaAreaBounds.width && !isMobile) { if (mediaContentSize.width < mediaAreaBounds.width * 0.8) { mediaBounds.width = mediaContentSize.width; @@ -579,7 +541,7 @@ const SmartLayout = (props) => { }); layoutContextDispatch({ - type: ACTIONS.SET_GENERIC_COMPONENT_OUTPUT, + type: ACTIONS.SET_GENERIC_CONTENT_OUTPUT, value: { width: mediaBounds.width, height: mediaBounds.height, diff --git a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/videoFocusLayout.jsx b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/videoFocusLayout.jsx index 14e58f622f..a0542d14c1 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/layout-manager/videoFocusLayout.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/layout-manager/videoFocusLayout.jsx @@ -10,7 +10,8 @@ import DEFAULT_VALUES from '/imports/ui/components/layout/defaultValues'; import { INITIAL_INPUT_STATE } from '/imports/ui/components/layout/initState'; import { ACTIONS, PANELS } from '/imports/ui/components/layout/enums'; import { defaultsDeep } from '/imports/utils/array-utils'; -import { isPresentationEnabled } from '/imports/ui/services/features'; +import Session from '/imports/ui/services/storage/in-memory'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const windowWidth = () => window.document.documentElement.clientWidth; const windowHeight = () => window.document.documentElement.clientHeight; @@ -28,14 +29,15 @@ const VideoFocusLayout = (props) => { const input = layoutSelect((i) => i.input); const deviceType = layoutSelect((i) => i.deviceType); - const isRTL = layoutSelect((i) => i.isRTL); + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application; const fullscreen = layoutSelect((i) => i.fullscreen); const fontSize = layoutSelect((i) => i.fontSize); const currentPanelType = layoutSelect((i) => i.currentPanelType); const presentationInput = layoutSelectInput((i) => i.presentation); const externalVideoInput = layoutSelectInput((i) => i.externalVideo); - const genericComponentInput = layoutSelectInput((i) => i.genericComponent); + const genericMainContentInput = layoutSelectInput((i) => i.genericMainContent); const screenShareInput = layoutSelectInput((i) => i.screenShare); const sharedNotesInput = layoutSelectInput((i) => i.sharedNotes); @@ -49,6 +51,7 @@ const VideoFocusLayout = (props) => { const sidebarContentOutput = layoutSelectOutput((i) => i.sidebarContent); const prevDeviceType = usePrevious(deviceType); + const { isPresentationEnabled } = props; const throttledCalculatesLayout = throttle(() => calculatesLayout(), 50, { trailing: true, @@ -77,18 +80,22 @@ const VideoFocusLayout = (props) => { } else { throttledCalculatesLayout(); } - }, [input, deviceType, isRTL, fontSize, fullscreen]); + }, [input, deviceType, isRTL, fontSize, fullscreen, isPresentationEnabled]); const init = () => { - const { sidebarContentPanel } = sidebarContentInput; - if (isMobile) { - layoutContextDispatch({ - type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( + layoutContextDispatch({ + type: ACTIONS.SET_LAYOUT_INPUT, + value: (prevInput) => { + const { + sidebarNavigation, sidebarContent, presentation, cameraDock, + externalVideo, genericMainContent, screenShare, + } = prevInput; + const { sidebarContentPanel } = sidebarContent; + return defaultsDeep( { sidebarNavigation: { isOpen: - input.sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, + sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, }, sidebarContent: { isOpen: sidebarContentPanel !== PANELS.NONE, @@ -98,87 +105,46 @@ const VideoFocusLayout = (props) => { isOpen: false, }, presentation: { - isOpen: presentationInput.isOpen, - slidesLength: presentationInput.slidesLength, + isOpen: presentation.isOpen, + slidesLength: presentation.slidesLength, currentSlide: { - ...presentationInput.currentSlide, + ...presentation.currentSlide, }, }, cameraDock: { - numCameras: cameraDockInput.numCameras, + numCameras: cameraDock.numCameras, }, externalVideo: { - hasExternalVideo: input.externalVideo.hasExternalVideo, + hasExternalVideo: externalVideo.hasExternalVideo, }, - genericComponent: { - genericComponentId: input.genericComponent.genericComponentId, + genericMainContent: { + genericContentId: genericMainContent.genericContentId, }, screenShare: { - hasScreenShare: input.screenShare.hasScreenShare, - width: input.screenShare.width, - height: input.screenShare.height, + hasScreenShare: screenShare.hasScreenShare, + width: screenShare.width, + height: screenShare.height, }, }, - INITIAL_INPUT_STATE - ), - }); - } else { - layoutContextDispatch({ - type: ACTIONS.SET_LAYOUT_INPUT, - value: defaultsDeep( - { - sidebarNavigation: { - isOpen: - input.sidebarNavigation.isOpen || sidebarContentPanel !== PANELS.NONE || false, - }, - sidebarContent: { - isOpen: sidebarContentPanel !== PANELS.NONE, - sidebarContentPanel, - }, - SidebarContentHorizontalResizer: { - isOpen: false, - }, - presentation: { - isOpen: presentationInput.isOpen, - slidesLength: presentationInput.slidesLength, - currentSlide: { - ...presentationInput.currentSlide, - }, - }, - cameraDock: { - numCameras: cameraDockInput.numCameras, - }, - externalVideo: { - hasExternalVideo: input.externalVideo.hasExternalVideo, - }, - genericComponent: { - genericComponentId: input.genericComponent.genericComponentId, - }, - screenShare: { - hasScreenShare: input.screenShare.hasScreenShare, - width: input.screenShare.width, - height: input.screenShare.height, - }, - }, - INITIAL_INPUT_STATE - ), - }); - } - Session.set('layoutReady', true); + INITIAL_INPUT_STATE, + ); + }, + }); + Session.setItem('layoutReady', true); throttledCalculatesLayout(); }; const calculatesSidebarContentHeight = () => { const { isOpen, slidesLength } = presentationInput; const { hasExternalVideo } = externalVideoInput; - const { genericComponentId } = genericComponentInput; + const { genericContentId } = genericMainContentInput; const { hasScreenShare } = screenShareInput; const { isPinned: isSharedNotesPinned } = sharedNotesInput; const navBarHeight = calculatesNavbarHeight(); - const hasPresentation = isPresentationEnabled() && slidesLength !== 0; + const hasPresentation = isPresentationEnabled && slidesLength !== 0; const isGeneralMediaOff = !hasPresentation && !hasExternalVideo - && !hasScreenShare && !isSharedNotesPinned && !genericComponentId; + && !hasScreenShare && !isSharedNotesPinned && !genericContentId; let minHeight = 0; let height = 0; @@ -271,7 +237,7 @@ const VideoFocusLayout = (props) => { fullscreenElement === 'Presentation' || fullscreenElement === 'Screenshare' || fullscreenElement === 'ExternalVideo' || - fullscreenElement === 'GenericComponent' + fullscreenElement === 'GenericContent' ) { mediaBounds.width = windowWidth(); mediaBounds.height = windowHeight(); @@ -517,7 +483,7 @@ const VideoFocusLayout = (props) => { }); layoutContextDispatch({ - type: ACTIONS.SET_GENERIC_COMPONENT_OUTPUT, + type: ACTIONS.SET_GENERIC_CONTENT_OUTPUT, value: { width: mediaBounds.width, height: mediaBounds.height, diff --git a/bigbluebutton-html5/imports/ui/components/layout/layoutTypes.ts b/bigbluebutton-html5/imports/ui/components/layout/layoutTypes.ts index 6d83e34737..dee1f13885 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/layoutTypes.ts +++ b/bigbluebutton-html5/imports/ui/components/layout/layoutTypes.ts @@ -16,7 +16,7 @@ interface PresentationAreaContentActions { value: { content: string, open: boolean, - genericComponentId?: string; + genericContentId?: string; }, } @@ -82,8 +82,8 @@ export interface ExternalVideo { right?: number; } -export interface GenericComponent { - genericComponentId?: string; +export interface GenericContentMainArea { + genericContentId?: string; browserHeight?: number; browserWidth?: number; height: number; @@ -246,9 +246,9 @@ interface Input { bannerBar: BannerBar; browser: Browser; cameraDock: CameraDock - customParameters: NonNullable; + userMetadata: NonNullable; externalVideo: ExternalVideo; - genericComponent: GenericComponent; + genericMainContent: GenericContentMainArea; navBar: NavBar; notificationsBar: NotificationsBar; presentation: Presentation; @@ -265,7 +265,7 @@ interface Output { captions: Captions; dropZoneAreas: DropzoneAreas; externalVideo: ExternalVideo; - genericComponent: GenericComponent; + genericMainContent: GenericContentMainArea; mediaArea: Size; navBar: NavBar; presentation: Presentation; diff --git a/bigbluebutton-html5/imports/ui/components/layout/modal/component.jsx b/bigbluebutton-html5/imports/ui/components/layout/modal/component.jsx index e363afa23e..9c5df4aa58 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/modal/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/modal/component.jsx @@ -7,19 +7,17 @@ import deviceInfo from '/imports/utils/deviceInfo'; import Button from '/imports/ui/components/common/button/component'; import Styled from './styles'; -const LayoutModalComponent = (props) => { - const { - intl, - setIsOpen, - isModerator, - isPresenter, - application, - updateSettings, - onRequestClose, - isOpen, - setLocalSettings, - } = props; - +const LayoutModalComponent = ({ + intl, + setIsOpen, + isModerator = false, + isPresenter, + application, + updateSettings, + onRequestClose, + isOpen, + setLocalSettings, +}) => { const [selectedLayout, setSelectedLayout] = useState(application.selectedLayout); const [updateAllUsed, setUpdateAllUsed] = useState(false); @@ -199,11 +197,6 @@ const propTypes = { setLocalSettings: PropTypes.func.isRequired, }; -const defaultProps = { - isModerator: false, -}; - LayoutModalComponent.propTypes = propTypes; -LayoutModalComponent.defaultProps = defaultProps; export default injectIntl(LayoutModalComponent); diff --git a/bigbluebutton-html5/imports/ui/components/layout/modal/container.jsx b/bigbluebutton-html5/imports/ui/components/layout/modal/container.jsx index f8c0a86d29..2150bdbb91 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/modal/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/modal/container.jsx @@ -1,26 +1,34 @@ import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; -import SettingsService from '/imports/ui/services/settings'; import LayoutModalComponent from './component'; - -import { - updateSettings, - isPresenter, -} from '/imports/ui/components/settings/service'; +import { updateSettings } from '/imports/ui/components/settings/service'; import useUserChangedLocalSettings from '/imports/ui/services/settings/hooks/useUserChangedLocalSettings'; +import useSettings from '/imports/ui/services/settings/hooks/useSettings'; +import { SETTINGS } from '/imports/ui/services/settings/enums'; +import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; const LayoutModalContainer = (props) => { - const { intl, setIsOpen,onRequestClose, isOpen, isModerator, isPresenter, - application, updateSettings, } = props; + const { + intl, setIsOpen, onRequestClose, isOpen, amIModerator, + } = props; const setLocalSettings = useUserChangedLocalSettings(); - return }; + const application = useSettings(SETTINGS.APPLICATION); + const { data: currentUser } = useCurrentUser((u) => ({ + presenter: u.presenter, + })); + return ( + + ); +}; -export default withTracker(({ amIModerator }) => ({ - application: SettingsService.application, - updateSettings, - isPresenter: isPresenter(), - isModerator: amIModerator, -}))(LayoutModalContainer); +export default LayoutModalContainer; diff --git a/bigbluebutton-html5/imports/ui/components/layout/push-layout/pushLayoutEngine.jsx b/bigbluebutton-html5/imports/ui/components/layout/push-layout/pushLayoutEngine.jsx index 8196cfd108..fb03995e16 100644 --- a/bigbluebutton-html5/imports/ui/components/layout/push-layout/pushLayoutEngine.jsx +++ b/bigbluebutton-html5/imports/ui/components/layout/push-layout/pushLayoutEngine.jsx @@ -1,15 +1,12 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Meteor } from 'meteor/meteor'; import getFromUserSettings from '/imports/ui/services/users-settings'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import MediaService from '/imports/ui/components/media/service'; import { LAYOUT_TYPE, ACTIONS } from '../enums'; import { isMobile } from '../utils'; import { updateSettings } from '/imports/ui/components/settings/service'; -import { Session } from 'meteor/session'; - -const HIDE_PRESENTATION = window.meetingClientSettings.public.layout.hidePresentationOnJoin; +import Session from '/imports/ui/services/storage/in-memory'; const equalDouble = (n1, n2) => { const precision = 0.01; @@ -70,6 +67,8 @@ class PushLayoutEngine extends React.Component { pushLayoutMeeting, } = this.props; + const Settings = getSettingsSingletonInstance(); + const changeLayout = LAYOUT_TYPE[getFromUserSettings('bbb_change_layout', null)]; const defaultLayout = LAYOUT_TYPE[getFromUserSettings('bbb_default_layout', null)]; const enforcedLayout = LAYOUT_TYPE[enforceLayout] || null; @@ -84,16 +83,18 @@ class PushLayoutEngine extends React.Component { selectedLayout = selectedLayout === 'custom' ? 'smart' : selectedLayout; Settings.application.selectedLayout = selectedLayout; } - Session.set('isGridEnabled', selectedLayout === LAYOUT_TYPE.VIDEO_FOCUS); + Session.setItem('isGridEnabled', selectedLayout === LAYOUT_TYPE.VIDEO_FOCUS); Settings.save(setLocalSettings); + const HIDE_PRESENTATION = window.meetingClientSettings.public.layout.hidePresentationOnJoin; + const shouldOpenPresentation = shouldShowScreenshare || shouldShowExternalVideo; let presentationIsOpen = !getFromUserSettings('bbb_hide_presentation_on_join', HIDE_PRESENTATION); presentationIsOpen = pushLayoutMeeting ? meetingPresentationIsOpen : presentationIsOpen; presentationIsOpen = shouldOpenPresentation || presentationIsOpen; MediaService.setPresentationIsOpen(layoutContextDispatch, presentationIsOpen); - Session.set('presentationLastState', presentationIsOpen); + Session.setItem('presentationLastState', presentationIsOpen); if (selectedLayout === 'custom') { setTimeout(() => { @@ -166,6 +167,7 @@ class PushLayoutEngine extends React.Component { const shouldSwitchLayout = isPresenter ? meetingLayoutDidChange || enforceLayoutDidChange : ((meetingLayoutDidChange || pushLayoutMeetingDidChange) && pushLayoutMeeting) || enforceLayoutDidChange; + const Settings = getSettingsSingletonInstance(); if (shouldSwitchLayout) { let contextLayout = enforceLayout || meetingLayout; @@ -278,7 +280,7 @@ class PushLayoutEngine extends React.Component { } if (selectedLayout !== prevProps.selectedLayout) { - Session.set('isGridEnabled', selectedLayout === LAYOUT_TYPE.VIDEO_FOCUS); + Session.setItem('isGridEnabled', selectedLayout === LAYOUT_TYPE.VIDEO_FOCUS); } } diff --git a/bigbluebutton-html5/imports/ui/components/learning-dashboard/service.js b/bigbluebutton-html5/imports/ui/components/learning-dashboard/service.js index dbfc64af6f..3a2080ba79 100644 --- a/bigbluebutton-html5/imports/ui/components/learning-dashboard/service.js +++ b/bigbluebutton-html5/imports/ui/components/learning-dashboard/service.js @@ -1,47 +1,18 @@ -import Users from '/imports/api/users'; import Auth from '/imports/ui/services/auth'; -import Meetings from '/imports/api/meetings'; -const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; - -const isModerator = () => { - const user = Users.findOne( - { - meetingId: Auth.meetingID, - userId: Auth.userID, - }, - { fields: { role: 1 } }, - ); - - if (user && user.role === ROLE_MODERATOR) { - return true; - } - - return false; -}; - -const getLearningDashboardAccessToken = () => (( - Meetings.findOne( - { meetingId: Auth.meetingID }, - { - fields: { 'learningDashboard.learningDashboardAccessToken': 1 }, - }, - ) || {})?.learningDashboard?.learningDashboardAccessToken || null); - -const setLearningDashboardCookie = () => { - const learningDashboardAccessToken = getLearningDashboardAccessToken(); - if (learningDashboardAccessToken !== null) { +const setLearningDashboardCookie = (token) => { + if (token !== null) { const lifetime = new Date(); lifetime.setTime(lifetime.getTime() + (3600000)); // 1h (extends 7d when open Dashboard) - document.cookie = `ld-${Auth.meetingID}=${getLearningDashboardAccessToken()}; expires=${lifetime.toGMTString()}; path=/`; + document.cookie = `ld-${Auth.meetingID}=${token}; expires=${lifetime.toGMTString()}; path=/`; return true; } return false; }; -const openLearningDashboardUrl = (lang) => { +const openLearningDashboardUrl = (lang, token) => { const APP = window.meetingClientSettings.public.app; - if (getLearningDashboardAccessToken() && setLearningDashboardCookie()) { + if (token && setLearningDashboardCookie(token)) { window.open(`${APP.learningDashboardBase}/?meeting=${Auth.meetingID}&lang=${lang}`, '_blank'); } else { window.open(`${APP.learningDashboardBase}/?meeting=${Auth.meetingID}&sessionToken=${Auth.sessionToken}&lang=${lang}`, '_blank'); @@ -49,8 +20,6 @@ const openLearningDashboardUrl = (lang) => { }; export default { - isModerator, - getLearningDashboardAccessToken, setLearningDashboardCookie, openLearningDashboardUrl, }; diff --git a/bigbluebutton-html5/imports/ui/components/legacy/component.jsx b/bigbluebutton-html5/imports/ui/components/legacy/component.jsx index a59254120f..f8475a4800 100755 --- a/bigbluebutton-html5/imports/ui/components/legacy/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/legacy/component.jsx @@ -70,8 +70,6 @@ const FETCHING = 'fetching'; const FALLBACK = 'fallback'; const READY = 'ready'; const supportedBrowsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'Microsoft Edge', 'Yandex Browser']; -const DEFAULT_LANGUAGE = window.meetingClientSettings.public.app.defaultSettings.application.fallbackLocale; -const CLIENT_VERSION = window.meetingClientSettings.public.app.html5ClientBuild; export default class Legacy extends Component { constructor(props) { @@ -85,6 +83,10 @@ export default class Legacy extends Component { const that = this; this.state = { viewState: FETCHING }; + + const DEFAULT_LANGUAGE = window.meetingClientSettings.public.app.defaultSettings.application.fallbackLocale; + const CLIENT_VERSION = window.meetingClientSettings.public.app.html5ClientBuild; + fetch(url) .then((response) => { if (!response.ok) { diff --git a/bigbluebutton-html5/imports/ui/components/lock-viewers/component.jsx b/bigbluebutton-html5/imports/ui/components/lock-viewers/component.jsx index ddcc6d3d5c..4134ed97f1 100755 --- a/bigbluebutton-html5/imports/ui/components/lock-viewers/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/lock-viewers/component.jsx @@ -3,7 +3,6 @@ import { defineMessages, injectIntl } from 'react-intl'; import PropTypes from 'prop-types'; import Toggle from '/imports/ui/components/common/switch/component'; import Styled from './styles'; -import { isChatEnabled, isSharedNotesEnabled } from '/imports/ui/services/features'; const intlMessages = defineMessages({ lockViewersTitle: { @@ -152,6 +151,8 @@ class LockViewersComponent extends Component { isOpen, onRequestClose, priority, + isChatEnabled, + isSharedNotesEnabled, } = this.props; const { lockSettingsProps, usersProp } = this.state; @@ -255,7 +256,7 @@ class LockViewersComponent extends Component { - {isChatEnabled() ? ( + {isChatEnabled ? ( ) : null } - {isSharedNotesEnabled() + {isSharedNotesEnabled ? (
) : null} - {noRating ? ( + setDispatched(true)} - aria-description={intl.formatMessage(intlMessage.confirmDesc)} + onClick={buttonAction} + aria-details={buttonDesc} + data-test={(!noRating && !dispatched) ? 'sendFeedbackButton' : null} > - {intl.formatMessage(intlMessage.buttonOkay)} + {buttonLabel} - ) : null} - {!noRating ? ( - - {intl.formatMessage(intlMessage.sendLabel)} - - ) : null} + ); - }, []); + }, [askForFeedbackOnLogout, dispatched, selectedStars]); useEffect(() => { // Sets Loading to falsed and removes loading splash screen @@ -359,7 +384,8 @@ const MeetingEnded: React.FC = ({ // Stops all media tracks window.dispatchEvent(new Event('StopAudioTracks')); // get the media tag from the session storage - const data = JSON.parse((sessionStorage.getItem('clientStartupSettings')) || '{}'); + // @ts-ignore + const data = window.meetingClientSettings.public.media; // get media element and stops it and removes the audio source const mediaElement = document.querySelector(data.mediaTag); if (mediaElement) { @@ -373,6 +399,8 @@ const MeetingEnded: React.FC = ({ apolloClient.stop(); } + apolloContextHolder.setShouldRetry(false); + const ws = apolloContextHolder.getLink(); // stops client connection after 5 seconds, if made immediately some data is lost if (ws) { @@ -381,7 +409,7 @@ const MeetingEnded: React.FC = ({ // if not new connection is made apolloClient.setLink(ApolloLink.empty()); // closes the connection - ws.close(); + ws.terminate(); }, 5000); } }, []); @@ -465,13 +493,16 @@ const MeetingEndedContainer: React.FC = ({ learningDashboardBase, } = clientSettings; + const shouldAskForFeedback = askForFeedbackOnLogout + || getFromUserSettings('bbb_ask_for_feedback_on_logout'); + return ( = (props) => { const [urlMessage, setUrlMessage] = useState(''); const intl = useIntl(); + const BBB_TABLET_APP_CONFIG = window.meetingClientSettings.public.app.bbbTabletApp; + useEffect(() => { const url = `/bigbluebutton/api/getJoinUrl?sessionToken=${sessionToken}`; const options = { diff --git a/bigbluebutton-html5/imports/ui/components/muted-alert/component.jsx b/bigbluebutton-html5/imports/ui/components/muted-alert/component.jsx index ecd2228a6e..1c6d1450e4 100644 --- a/bigbluebutton-html5/imports/ui/components/muted-alert/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/muted-alert/component.jsx @@ -7,8 +7,6 @@ import { defineMessages, injectIntl } from 'react-intl'; import { notify } from '/imports/ui/services/notification'; import TooltipContainer from '/imports/ui/components/common/tooltip/container'; -const MUTE_ALERT_CONFIG = window.meetingClientSettings.public.app.mutedAlert; - const propTypes = { inputStream: PropTypes.objectOf(PropTypes.any).isRequired, isPresenter: PropTypes.bool.isRequired, @@ -49,6 +47,8 @@ class MutedAlert extends Component { } componentDidMount() { + const MUTE_ALERT_CONFIG = window.meetingClientSettings.public.app.mutedAlert; + this._isMounted = true; if (!this.hasValidInputStream()) return; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx index e5a6c52f14..2b4ff891df 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx @@ -17,7 +17,7 @@ import deviceInfo from '/imports/utils/deviceInfo'; import { PANELS, ACTIONS, LAYOUT_TYPE } from '../layout/enums'; import Button from '/imports/ui/components/common/button/component'; import LeaveMeetingButtonContainer from './leave-meeting-button/container'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const intlMessages = defineMessages({ toggleUserListLabel: { @@ -284,11 +284,15 @@ class NavBar extends Component { const { leftPluginItems, centerPluginItems, rightPluginItems } = this.splitPluginItems(); + const Settings = getSettingsSingletonInstance(); const { selectedLayout } = Settings.application; const shouldShowNavBarToggleButton = selectedLayout !== LAYOUT_TYPE.CAMERAS_ONLY && selectedLayout !== LAYOUT_TYPE.PRESENTATION_ONLY && selectedLayout !== LAYOUT_TYPE.PARTICIPANTS_AND_CHAT_ONLY; + const APP_CONFIG = window.meetingClientSettings?.public?.app; + const enableTalkingIndicator = APP_CONFIG?.enableTalkingIndicator; + return ( - + {enableTalkingIndicator ? : null} diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx index 4c531a6d0a..2c743e776d 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx @@ -1,8 +1,5 @@ import React, { useContext } from 'react'; -import { Meteor } from 'meteor/meteor'; -import { withTracker } from 'meteor/react-meteor-data'; -import Meetings from '/imports/api/meetings'; -import Breakouts from '/imports/api/breakouts'; +import { defineMessages, useIntl } from 'react-intl'; import Auth from '/imports/ui/services/auth'; import getFromUserSettings from '/imports/ui/services/users-settings'; import NavBar from './component'; @@ -13,12 +10,20 @@ import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; import useChat from '/imports/ui/core/hooks/useChat'; import useHasUnreadNotes from '../notes/hooks/useHasUnreadNotes'; import { useShortcut } from '../../core/hooks/useShortcut'; +import useMeeting from '../../core/hooks/useMeeting'; +import { registerTitleView } from '/imports/utils/dom-utils'; -const PUBLIC_CONFIG = window.meetingClientSettings.public; +const intlMessages = defineMessages({ + defaultViewLabel: { + id: 'app.title.defaultViewLabel', + description: 'view name appended to document title', + }, +}); const NavBarContainer = ({ children, ...props }) => { const { pluginsExtensibleAreasAggregatedState } = useContext(PluginsContext); const unread = useHasUnreadNotes(); + const intl = useIntl(); const sidebarContent = layoutSelectInput((i) => i.sidebarContent); const sidebarNavigation = layoutSelectInput((i) => i.sidebarNavigation); @@ -49,6 +54,41 @@ const NavBarContainer = ({ children, ...props }) => { const hideNavBar = getFromUserSettings('bbb_hide_nav_bar', false); + const PUBLIC_CONFIG = window.meetingClientSettings.public; + const CLIENT_TITLE = getFromUserSettings('bbb_client_title', PUBLIC_CONFIG.app.clientTitle); + const IS_DIRECT_LEAVE_BUTTON_ENABLED = getFromUserSettings( + 'bbb_direct_leave_button', + PUBLIC_CONFIG.app.defaultSettings.application.directLeaveButton, + ); + + let meetingTitle; + let breakoutNum; + let breakoutName; + let meetingName; + + const { data: meeting } = useMeeting((m) => ({ + name: m.name, + meetingId: m.meetingId, + breakoutPolicies: { + sequence: m.breakoutPolicies.sequence, + }, + })); + + if (meeting) { + meetingTitle = meeting.name; + const titleString = `${CLIENT_TITLE} - ${meetingTitle}`; + document.title = titleString; + registerTitleView(intl.formatMessage(intlMessages.defaultViewLabel)); + + if (meeting.breakoutPolicies) { + breakoutNum = meeting.breakoutPolicies.sequence; + if (breakoutNum > 0) { + breakoutName = meetingTitle; + meetingName = meetingTitle.replace(`(${breakoutName})`, '').trim(); + } + } + } + if (hideNavBar || navBar.display === false) return null; let pluginNavBarItems = []; @@ -73,6 +113,14 @@ const NavBarContainer = ({ children, ...props }) => { currentUserId: Auth.userID, pluginNavBarItems, shortcuts: toggleUserList, + meetingId: meeting?.meetingId, + presentationTitle: meetingTitle, + breakoutNum, + breakoutName, + meetingName, + isDirectLeaveButtonEnabled: IS_DIRECT_LEAVE_BUTTON_ENABLED, + // TODO: Remove/Replace + isMeteorConnected: true, ...props, }} style={{ ...navBar }} @@ -82,47 +130,4 @@ const NavBarContainer = ({ children, ...props }) => { ); }; -export default withTracker(() => { - const CLIENT_TITLE = getFromUserSettings('bbb_client_title', PUBLIC_CONFIG.app.clientTitle); - - let meetingTitle, breakoutNum, breakoutName, meetingName; - const meetingId = Auth.meetingID; - const meetingObject = Meetings.findOne({ - meetingId, - }, { fields: { name: 1, 'breakoutPolicies.sequence': 1, meetingId: 1 } }); - - if (meetingObject != null) { - meetingTitle = meetingObject.name; - let titleString = `${CLIENT_TITLE} - ${meetingTitle}`; - document.title = titleString; - - if (meetingObject.breakoutPolicies) { - breakoutNum = meetingObject.breakoutPolicies.sequence; - if (breakoutNum > 0) { - const breakoutObject = Breakouts.findOne({ - breakoutId: meetingObject.meetingId, - }, { fields: { shortName: 1 } }); - if (breakoutObject) { - breakoutName = breakoutObject.shortName; - meetingName = meetingTitle.replace(`(${breakoutName})`, '').trim(); - } - } - } - } - - const IS_DIRECT_LEAVE_BUTTON_ENABLED = getFromUserSettings( - 'bbb_direct_leave_button', - PUBLIC_CONFIG.app.defaultSettings.application.directLeaveButton, - ); - - return { - currentUserId: Auth.userID, - meetingId, - presentationTitle: meetingTitle, - breakoutNum, - breakoutName, - meetingName, - isDirectLeaveButtonEnabled: IS_DIRECT_LEAVE_BUTTON_ENABLED, - isMeteorConnected: Meteor.status().connected, - }; -})(NavBarContainer); +export default NavBarContainer; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/leave-meeting-button/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/leave-meeting-button/component.jsx index d6fd0d8562..ec9fde1ae9 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/leave-meeting-button/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/leave-meeting-button/component.jsx @@ -5,6 +5,7 @@ import EndMeetingConfirmationContainer from '/imports/ui/components/end-meeting- import BBBMenu from '/imports/ui/components/common/menu/component'; import { colorDanger, colorWhite } from '/imports/ui/stylesheets/styled-components/palette'; import Styled from './styles'; +import Session from '/imports/ui/services/storage/in-memory'; const intlMessages = defineMessages({ leaveMeetingBtnLabel: { @@ -39,7 +40,7 @@ const propTypes = { }).isRequired, amIModerator: PropTypes.bool, isBreakoutRoom: PropTypes.bool, - isMeteorConnected: PropTypes.bool.isRequired, + connected: PropTypes.bool.isRequired, isDropdownOpen: PropTypes.bool, isMobile: PropTypes.bool.isRequired, userLeaveMeeting: PropTypes.func.isRequired, @@ -77,12 +78,12 @@ class LeaveMeetingButton extends PureComponent { userLeaveMeeting(); // we don't check askForFeedbackOnLogout here, // it is checked in meeting-ended component - Session.set('codeError', this.LOGOUT_CODE); + Session.setItem('codeError', this.LOGOUT_CODE); } renderMenuItems() { const { - intl, amIModerator, isBreakoutRoom, isMeteorConnected, + intl, amIModerator, isBreakoutRoom, connected, } = this.props; const allowedToEndMeeting = amIModerator && !isBreakoutRoom; @@ -91,7 +92,7 @@ class LeaveMeetingButton extends PureComponent { this.menuItems = []; - if (allowLogoutSetting && isMeteorConnected) { + if (allowLogoutSetting && connected) { this.menuItems.push( { key: 'list-item-logout', @@ -104,7 +105,7 @@ class LeaveMeetingButton extends PureComponent { ); } - if (allowedToEndMeeting && isMeteorConnected) { + if (allowedToEndMeeting && connected) { const customStyles = { background: colorDanger, color: colorWhite }; this.menuItems.push( @@ -163,6 +164,7 @@ class LeaveMeetingButton extends PureComponent { trigger={( { - const { width: browserWidth } = layoutSelectInput((i) => i.browser); - const isMobile = browserWidth <= SMALL_VIEWPORT_BREAKPOINT; + const { + data: currentUser, + } = useCurrentUser((u) => ({ + isModerator: u.isModerator, + })); + + const { + data: meeting, + } = useMeeting((m) => ({ + isBreakout: m.isBreakout, + })); + + const { isMobile } = deviceInfo; const isRTL = layoutSelect((i) => i.isRTL); const [userLeaveMeeting] = useMutation(USER_LEAVE_MEETING); + const isDropdownOpen = useStorageKey('dropdownOpen'); + const connected = useReactiveVar(connectionStatus.getConnectedStatusVar()); + const amIModerator = currentUser?.isModerator; + const isBreakoutRoom = meeting?.isBreakout; return ( ); }; -export default withTracker((props) => ({ - amIModerator: props.amIModerator, - isMobile: deviceInfo.isMobile, - isMeteorConnected: Meteor.status().connected, - isBreakoutRoom: meetingIsBreakout(), - isDropdownOpen: Session.get('dropdownOpen'), -}))(LeaveMeetingButtonContainer); +export default LeaveMeetingButtonContainer; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/leave-meeting-button/styles.js b/bigbluebutton-html5/imports/ui/components/nav-bar/leave-meeting-button/styles.js index 257adab113..e5652a0d68 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/leave-meeting-button/styles.js +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/leave-meeting-button/styles.js @@ -8,9 +8,13 @@ const LeaveButton = styled(Button)` display: none; } `} - ${({ state }) => state === 'closed' && ` + + ${({ state, isMobile }) => state === 'closed' && !isMobile && ` margin-left: 1.0rem; margin-right: 0.5rem; + `} + + ${({ state }) => state === 'closed' && ` border-radius: 1.1rem; font-size: 1rem; line-height: 1.1rem; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/component.tsx b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/component.tsx index efa59f1586..a164a86130 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/component.tsx @@ -6,7 +6,6 @@ import React, { } from 'react'; import useMeeting from '/imports/ui/core/hooks/useMeeting'; import deviceInfo from '/imports/utils/deviceInfo'; -import { useSubscription } from '@apollo/client'; import { GET_MEETING_RECORDING_DATA, GET_MEETING_RECORDING_POLICIES, @@ -25,6 +24,9 @@ import { defineMessages, useIntl } from 'react-intl'; import useTimeSync from '/imports/ui/core/local-states/useTimeSync'; import RecordingNotify from './notify/component'; import RecordingContainer from '/imports/ui/components/recording/container'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; +import logger from '/imports/startup/client/logger'; const intlMessages = defineMessages({ notificationRecordingStart: { @@ -63,6 +65,18 @@ const intlMessages = defineMessages({ id: 'app.navBar.emptyAudioBrdige', description: 'message for notification when recording starts with no users in audio bridge', }, + errorDescription: { + id: 'app.recording.errorDescription', + description: 'recording data error', + }, + loadingDescription: { + id: 'app.recording.loadingDescription', + description: 'recording data is loading', + }, + unavailableTitle: { + id: 'app.navBar.recording.unavailable', + description: 'recording data is either loading or failed to load', + }, }); interface RecordingIndicatorProps { @@ -76,6 +90,8 @@ interface RecordingIndicatorProps { recordingNotificationEnabled: boolean; serverTime: number; isModerator: boolean; + hasError: boolean; + isLoading: boolean; } const RecordingIndicator: React.FC = ({ @@ -87,6 +103,8 @@ const RecordingIndicator: React.FC = ({ isModerator, record, recordingNotificationEnabled, + hasError, + isLoading, }) => { const intl = useIntl(); const [isRecordingModalOpen, setIsRecordingModalOpen] = useState(false); @@ -94,6 +112,7 @@ const RecordingIndicator: React.FC = ({ const [shouldNotify, setShouldNotify] = useState(true); const [time, setTime] = useState(0); const setIntervalRef = React.useRef>(); + const disabled = hasError || isLoading; const recordingToggle = useCallback((hasMicUser: boolean, isRecording: boolean) => { if (!hasMicUser && !isRecording) { @@ -124,7 +143,7 @@ const RecordingIndicator: React.FC = ({ if (recordingNotificationEnabled && recording) { setShouldNotify(true); } - }, []); + }, [recordingNotificationEnabled, recording]); useEffect(() => { if (recordingNotificationEnabled) { @@ -136,13 +155,15 @@ const RecordingIndicator: React.FC = ({ }, [shouldNotify, recordingNotificationEnabled, recording]); const recordTitle = useMemo(() => { - if (!isPhone && !recording) { + if (isPhone) return ''; + if (disabled) return intl.formatMessage(intlMessages.unavailableTitle); + if (!recording) { return time > 0 ? intl.formatMessage(intlMessages.resumeTitle) : intl.formatMessage(intlMessages.startTitle); } return intl.formatMessage(intlMessages.stopTitle); - }, [recording, isPhone]); + }, [recording, isPhone, disabled]); const recordingIndicatorIcon = useMemo(() => ( = ({ : intlMessages.recordingIndicatorOff, ), [recording]); - const recordMeetingButton = useMemo(() => ( + let recordMeetingButton = ( { recordingToggle(micUser, recording); }} - onKeyPress={() => { + onKeyDown={() => { recordingToggle(micUser, recording); }} > @@ -208,13 +229,29 @@ const RecordingIndicator: React.FC = ({ )} - ), [recording, micUser, time]); + ); - const recordMeetingButtonWithTooltip = useMemo(() => ( + const recordMeetingButtonWithTooltip = ( {recordMeetingButton} - ), [recording, micUser, time]); + ); + + if (disabled) { + recordMeetingButton = ( + + + {recordMeetingButton} + + + ); + } const recordingButton = recording ? recordMeetingButtonWithTooltip : recordMeetingButton; const showButton = isModerator && allowStartStopRecording; @@ -286,13 +323,13 @@ const RecordingIndicatorContainer: React.FC = () => { data: meetingRecordingPoliciesData, loading: meetingRecordingPoliciesLoading, error: meetingRecordingPoliciesError, - } = useSubscription(GET_MEETING_RECORDING_POLICIES); + } = useDeduplicatedSubscription(GET_MEETING_RECORDING_POLICIES); const { data: meetingRecordingData, loading: meetingRecordingLoading, error: meetingRecordingError, - } = useSubscription(GET_MEETING_RECORDING_DATA); + } = useDeduplicatedSubscription(GET_MEETING_RECORDING_DATA); const { data: currentUser } = useCurrentUser((user: Partial) => ({ userId: user.userId, @@ -311,18 +348,52 @@ const RecordingIndicatorContainer: React.FC = () => { })); const [timeSync] = useTimeSync(); + const Settings = getSettingsSingletonInstance(); + const animations = Settings?.application?.animations; - if (meetingRecordingPoliciesLoading || meetingRecordingLoading) return null; - if (meetingRecordingPoliciesError || meetingRecordingError) { + if (meetingRecordingPoliciesLoading || meetingRecordingLoading) { return ( -
- {JSON.stringify(meetingRecordingPoliciesError) - || JSON.stringify(meetingRecordingData)} -
+ <> + +
+ + + + +
+ ); } + if (meetingRecordingPoliciesError) { + logger.error({ + logCode: 'meeting_recordingPolicies_sub_error', + extraInfo: { + errorName: meetingRecordingPoliciesError.name, + errorMessage: meetingRecordingPoliciesError.message, + }, + }, 'Meeting recording policies subscription failed.'); + } - const meetingRecordingPolicies = meetingRecordingPoliciesData?.meeting_recordingPolicies[0]; + if (meetingRecordingError) { + logger.error({ + logCode: 'meeting_recording_sub_error', + extraInfo: { + errorName: meetingRecordingError.name, + errorMessage: meetingRecordingError.message, + }, + }, 'Meeting recording subscription failed.'); + } + + const meetingRecordingPolicies = meetingRecordingPoliciesData?.meeting_recordingPolicies[0] || { + allowStartStopRecording: false, + autoStartRecording: false, + record: false, + keepEvents: false, + startedAt: null, + startedBy: null, + stoppedAt: null, + stoppedBy: null, + }; meetingRecordingPoliciesAssertion(meetingRecordingPolicies); const meetingRecording = meetingRecordingData?.meeting_recording[0] || { @@ -355,6 +426,8 @@ const RecordingIndicatorContainer: React.FC = () => { } serverTime={passedTime > 0 ? passedTime : 0} isModerator={currentUser?.isModerator ?? false} + hasError={Boolean(meetingRecordingPoliciesError || meetingRecordingError)} + isLoading={meetingRecordingPoliciesLoading || meetingRecordingLoading} /> ); }; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/notify/component.tsx b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/notify/component.tsx index 9f6d569511..92cd14ad43 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/notify/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/notify/component.tsx @@ -2,6 +2,7 @@ import React, { Dispatch, SetStateAction, useCallback } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { USER_LEAVE_MEETING } from '/imports/ui/core/graphql/mutations/userMutations'; import { useMutation } from '@apollo/client'; +import Session from '/imports/ui/services/storage/in-memory'; import Styled from './styles'; @@ -57,7 +58,7 @@ const RecordingNotifyModal: React.FC = ({ userLeaveMeeting(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore Session is a global variable in Meteor - Session.set('codeError', LOGOUT_CODE); + Session.setItem('codeError', LOGOUT_CODE); toggleShouldNotify(); }, []); return ( diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/styles.ts b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/styles.ts index 1a32381b1e..aa25e57bb5 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/recording-indicator/styles.ts @@ -1,4 +1,4 @@ -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; import { fontSizeLarge, fontSizeBase } from '/imports/ui/stylesheets/styled-components/typography'; import { smPaddingX, @@ -12,6 +12,7 @@ import { colorDangerDark, colorGray, } from '/imports/ui/stylesheets/styled-components/palette'; +import SpinnerStyles from '/imports/ui/components/common/loading-screen/styles'; interface RecordingIndicatorIconProps { titleMargin: boolean; @@ -19,12 +20,17 @@ interface RecordingIndicatorIconProps { interface RecordingIndicatorProps { recording: boolean; + disabled: boolean; } interface RecordingStatusViewOnlyProps { recording: boolean; } +interface SpinnerOverlayProps { + animations: boolean; +} + const RecordingIndicatorIcon = styled.span` width: ${fontSizeLarge}; height: ${fontSizeLarge}; @@ -38,10 +44,11 @@ const RecordingIndicatorIcon = styled.span` `} `; -const RecordingControl = styled.div` +const RecordingControl = styled.button` display: flex; align-items: center; user-select: none; + background: none; span { border: none; @@ -50,7 +57,7 @@ const RecordingControl = styled.div` color: ${colorWhite} !important; } - &:hover { + &:hover:not(:disabled) { color: ${colorWhite} !important; cursor: pointer; } @@ -83,6 +90,11 @@ const RecordingControl = styled.div` box-shadow: none; } `} + + ${({ disabled }) => disabled && css` + cursor: not-allowed; + opacity: .5; + `} `; const PresentationTitle = styled.div` @@ -157,6 +169,24 @@ const RecordingStatusViewOnly = styled.div` `} `; +const SpinnerOverlay = styled(SpinnerStyles.Spinner)` + & > div { + background-color: white; + height: 0.5625rem; + width: 0.5625rem; + } +`; + +const Bounce1 = styled(SpinnerStyles.Bounce1)` + height: 0.5625rem; + width: 0.5625rem; +`; + +const Bounce2 = styled(SpinnerStyles.Bounce2)` + height: 0.5625rem; + width: 0.5625rem; +`; + export default { RecordingIndicatorIcon, RecordingControl, @@ -165,4 +195,7 @@ export default { PresentationTitleSeparator, RecordingIndicator, RecordingStatusViewOnly, + SpinnerOverlay, + Bounce1, + Bounce2, }; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/talking-indicator/component.tsx b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/talking-indicator/component.tsx index 284c6540f2..c11b26d7f5 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/talking-indicator/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/talking-indicator/component.tsx @@ -1,31 +1,25 @@ -import { useSubscription } from '@apollo/client'; import React, { useEffect, useMemo } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { IsBreakoutSubscriptionData, MEETING_ISBREAKOUT_SUBSCRIPTION, } from './queries'; -import { UserVoice } from '/imports/ui/Types/userVoice'; import { uniqueId } from '/imports/utils/string-utils'; import Styled from './styles'; import { User } from '/imports/ui/Types/user'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; import { muteUser } from './service'; import useToggleVoice from '../../../audio/audio-graphql/hooks/useToggleVoice'; -import TALKING_INDICATOR_SUBSCRIPTION from '/imports/ui/core/graphql/queries/userVoiceSubscription'; import { setTalkingIndicatorList } from '/imports/ui/core/hooks/useTalkingIndicator'; - -interface TalkingIndicatorSubscriptionData { - user_voice: Array>; -} - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore - temporary, while meteor exists in the project -const APP_CONFIG = window.meetingClientSettings.public.app; -const { enableTalkingIndicator } = APP_CONFIG; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; +import { VoiceActivityResponse } from '/imports/ui/core/graphql/queries/whoIsTalking'; +import useTalkingUsers from '/imports/ui/core/hooks/useTalkingUsers'; +import { partition } from '/imports/utils/array-utils'; const TALKING_INDICATORS_MAX = 8; +type VoiceItem = VoiceActivityResponse['user_voice_activity_stream'][number]; + const intlMessages = defineMessages({ wasTalking: { id: 'app.talkingIndicator.wasTalking', @@ -54,11 +48,11 @@ const intlMessages = defineMessages({ }); interface TalkingIndicatorProps { - talkingUsers: Array>; + talkingUsers: Array; isBreakout: boolean; moreThanMaxIndicators: boolean; isModerator: boolean; - toggleVoice: (userId?: string | null, muted?: boolean | null) => void; + toggleVoice: (userId: string, muted: boolean) => void; } const TalkingIndicator: React.FC = ({ @@ -75,14 +69,38 @@ const TalkingIndicator: React.FC = ({ setTalkingIndicatorList([]); }; }, []); - const talkingElements = useMemo(() => talkingUsers.map((talkingUser: Partial) => { + + const filteredTalkingUsers = talkingUsers.map((talkingUser) => { const { talking, muted, - user: { color, speechLocale } = {} as Partial, + user: { + color, + speechLocale, + name, + }, + userId, + } = talkingUser; + return { + talking, + muted, + color, + speechLocale, + name, + userId, + }; + }); + + const talkingElements = useMemo(() => filteredTalkingUsers.map((talkingUser) => { + const { + talking, + muted, + color, + speechLocale, + name, + userId, } = talkingUser; - const name = talkingUser.user?.name; const ariaLabel = intl.formatMessage(talking ? intlMessages.isTalking : intlMessages.wasTalking, { 0: name, @@ -91,7 +109,7 @@ const TalkingIndicator: React.FC = ({ icon = muted ? 'mute' : icon; return ( @@ -106,11 +124,11 @@ const TalkingIndicator: React.FC = ({ $spoke={!talking || undefined} $muted={muted || undefined} $isViewer={!isModerator || undefined} - key={uniqueId(`${name}-`)} + key={userId} onClick={() => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - call signature is misse due the function being wrapped - muteUser(talkingUser.userId, muted, isBreakout, isModerator, toggleVoice); + muteUser(userId, muted, isBreakout, isModerator, toggleVoice); }} label={name} tooltipLabel={!muted && isModerator @@ -135,18 +153,18 @@ const TalkingIndicator: React.FC = ({ ); - }), [talkingUsers]); + }), [filteredTalkingUsers]); const maxIndicator = () => { if (!moreThanMaxIndicators) return null; - const nobodyTalking = talkingUsers.every((user) => !user.talking); + const nobodyTalking = filteredTalkingUsers.every((user) => !user.talking); const { moreThanMaxIndicatorsTalking, moreThanMaxIndicatorsWereTalking } = intlMessages; const ariaLabel = intl.formatMessage(nobodyTalking ? moreThanMaxIndicatorsWereTalking : moreThanMaxIndicatorsTalking, { - 0: talkingUsers.length, + 0: filteredTalkingUsers.length, }); return ( @@ -181,48 +199,64 @@ const TalkingIndicator: React.FC = ({ }; const TalkingIndicatorContainer: React.FC = (() => { - if (!enableTalkingIndicator) return () => null; return () => { const { data: currentUser } = useCurrentUser((u: Partial) => ({ userId: u?.userId, isModerator: u?.isModerator, })); - const { - data: talkingIndicatorData, - loading: talkingIndicatorLoading, - error: talkingIndicatorError, - } = useSubscription( - TALKING_INDICATOR_SUBSCRIPTION, - { - variables: { - limit: TALKING_INDICATORS_MAX, - }, - }, - ); - const { data: isBreakoutData, loading: isBreakoutLoading, error: isBreakoutError, - } = useSubscription(MEETING_ISBREAKOUT_SUBSCRIPTION); + } = useDeduplicatedSubscription(MEETING_ISBREAKOUT_SUBSCRIPTION); const toggleVoice = useToggleVoice(); + const { data: talkingUsersData, loading: talkingUsersLoading } = useTalkingUsers(); + const talkingUsers = useMemo(() => { + const [muted, unmuted] = partition( + Object.values(talkingUsersData), + (v: VoiceItem) => v.muted, + ) as [VoiceItem[], VoiceItem[]]; + const [talking, silent] = partition( + unmuted, + (v: VoiceItem) => v.talking, + ) as [VoiceItem[], VoiceItem[]]; + return [ + ...talking.sort((v1, v2) => { + if (!v1.startTime && !v2.startTime) return 0; + if (!v1.startTime) return 1; + if (!v2.startTime) return -1; + return v1.startTime - v2.startTime; + }), + ...silent.sort((v1, v2) => { + if (!v1.endTime && !v2.endTime) return 0; + if (!v1.endTime) return 1; + if (!v2.endTime) return -1; + return v2.endTime - v1.endTime; + }), + ...muted.sort((v1, v2) => { + if (!v1.endTime && !v2.endTime) return 0; + if (!v1.endTime) return 1; + if (!v2.endTime) return -1; + return v2.endTime - v1.endTime; + }), + ].slice(0, TALKING_INDICATORS_MAX); + }, [talkingUsersData]); - if (talkingIndicatorLoading || isBreakoutLoading) return null; + if (talkingUsersLoading || isBreakoutLoading) return null; - if (talkingIndicatorError || isBreakoutError) { + if (isBreakoutError) { return (
error: - { JSON.stringify(talkingIndicatorError || isBreakoutError) } + { JSON.stringify(isBreakoutError) }
); } - const talkingUsers = talkingIndicatorData?.user_voice ?? []; const isBreakout = isBreakoutData?.meeting[0]?.isBreakout ?? false; - setTalkingIndicatorList(talkingUsers); + setTalkingIndicatorList(talkingUsers.map(({ user, ...rest }) => ({ ...rest, ...user }))); return ( void, + toggleVoice: (userId: string, muted: boolean) => void, ) => { if (!isModerator || isBreakout || muted) return null; - toggleVoice(id); + toggleVoice(id, true); return null; }, ); diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/options-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/options-dropdown/component.jsx index 9dd7df51df..0868b60304 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/options-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/options-dropdown/component.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import EndMeetingConfirmationContainer from '/imports/ui/components/end-meeting-confirmation/container'; import AboutContainer from '/imports/ui/components/about/container'; import MobileAppModal from '/imports/ui/components/mobile-app-modal/mobile-app-modal-graphql/component'; +import LayoutModalContainer from '/imports/ui/components/layout/modal/container'; import OptionsMenuContainer from '/imports/ui/components/settings/container'; import BBBMenu from '/imports/ui/components/common/menu/component'; import ShortcutHelpComponent from '/imports/ui/components/shortcut-help/component'; @@ -13,6 +14,9 @@ import { OptionsDropdownItemType } from 'bigbluebutton-html-plugin-sdk/dist/cjs/ import Styled from './styles'; import browserInfo from '/imports/utils/browserInfo'; import deviceInfo from '/imports/utils/deviceInfo'; +import Session from '/imports/ui/services/storage/in-memory'; +import { LAYOUT_TYPE } from '/imports/ui/components/layout/enums'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const intlMessages = defineMessages({ optionsLabel: { @@ -95,6 +99,10 @@ const intlMessages = defineMessages({ id: 'app.audio.captions.button.stop', description: 'Stop audio captions', }, + layoutModal: { + id: 'app.actionsBar.actionsDropdown.layoutModal', + description: 'Label for layouts selection button', + }, }); const propTypes = { @@ -129,8 +137,6 @@ const defaultProps = { audioCaptionsEnabled: false, }; -const ALLOW_FULLSCREEN = window.meetingClientSettings.public.app.allowFullscreen; -const BBB_TABLET_APP_CONFIG = window.meetingClientSettings.public.app.bbbTabletApp; const { isSafari, isTabletApp } = browserInfo; const FULLSCREEN_CHANGE_EVENT = isSafari ? 'webkitfullscreenchange' : 'fullscreenchange'; @@ -145,6 +151,7 @@ class OptionsDropdown extends PureComponent { isEndMeetingConfirmationModalOpen: false, isMobileAppModalOpen: false, isFullscreen: false, + isLayoutModalOpen: false, }; // Set the logout code to 680 because it's not a real code and can be matched on the other side @@ -157,6 +164,7 @@ class OptionsDropdown extends PureComponent { this.setMobileAppModalIsOpen = this.setMobileAppModalIsOpen.bind(this); this.setAboutModalIsOpen = this.setAboutModalIsOpen.bind(this); this.setShortcutHelpModalIsOpen = this.setShortcutHelpModalIsOpen.bind(this); + this.setLayoutModalIsOpen = this.setLayoutModalIsOpen.bind(this); } componentDidMount() { @@ -183,6 +191,8 @@ class OptionsDropdown extends PureComponent { } = this.props; const { isFullscreen } = this.state; + const ALLOW_FULLSCREEN = window.meetingClientSettings.public.app.allowFullscreen; + if (noIOSFullscreen || !ALLOW_FULLSCREEN) return null; let fullscreenLabel = intl.formatMessage(intlMessages.fullscreenLabel); @@ -214,7 +224,7 @@ class OptionsDropdown extends PureComponent { userLeaveMeeting(); // we don't check askForFeedbackOnLogout here, // it is checked in meeting-ended component - Session.set('codeError', this.LOGOUT_CODE); + Session.setItem('codeError', this.LOGOUT_CODE); } setAboutModalIsOpen(value) { @@ -237,10 +247,15 @@ class OptionsDropdown extends PureComponent { this.setState({isMobileAppModalOpen: value}) } + setLayoutModalIsOpen(value) { + this.setState({ isLayoutModalOpen: value }); + } + renderMenuItems() { const { intl, amIModerator, isBreakoutRoom, isMeteorConnected, audioCaptionsEnabled, - audioCaptionsActive, audioCaptionsSet, isMobile, optionsDropdownItems, isDirectLeaveButtonEnabled, + audioCaptionsActive, audioCaptionsSet, isMobile, optionsDropdownItems, + isDirectLeaveButtonEnabled, isLayoutsEnabled, } = this.props; const { isIos } = deviceInfo; @@ -257,6 +272,8 @@ class OptionsDropdown extends PureComponent { this.getFullscreenItem(this.menuItems); + const BBB_TABLET_APP_CONFIG = window.meetingClientSettings.public.app.bbbTabletApp; + this.menuItems.push( { key: 'list-item-settings', @@ -328,6 +345,23 @@ class OptionsDropdown extends PureComponent { }, ); + const Settings = getSettingsSingletonInstance(); + const { selectedLayout } = Settings.application; + const shouldShowManageLayoutButton = selectedLayout !== LAYOUT_TYPE.CAMERAS_ONLY + && selectedLayout !== LAYOUT_TYPE.PRESENTATION_ONLY + && selectedLayout !== LAYOUT_TYPE.PARTICIPANTS_AND_CHAT_ONLY; + + if (shouldShowManageLayoutButton && isLayoutsEnabled) { + this.menuItems.push( + { + key: 'list-item-layout-modal', + icon: 'manage_layout', + label: intl.formatMessage(intlMessages.layoutModal), + onClick: () => this.setLayoutModalIsOpen(true), + }, + ); + } + optionsDropdownItems.forEach((item) => { switch (item.type) { case OptionsDropdownItemType.OPTION: @@ -406,8 +440,10 @@ class OptionsDropdown extends PureComponent { isRTL, } = this.props; - const { isAboutModalOpen, isShortcutHelpModalOpen, isOptionsMenuModalOpen, - isEndMeetingConfirmationModalOpen, isMobileAppModalOpen, } = this.state; + const { + isAboutModalOpen, isShortcutHelpModalOpen, isOptionsMenuModalOpen, + isEndMeetingConfirmationModalOpen, isMobileAppModalOpen, isLayoutModalOpen, + } = this.state; const customStyles = { top: '1rem' }; @@ -453,6 +489,13 @@ class OptionsDropdown extends PureComponent { "low", EndMeetingConfirmationContainer)} {this.renderModal(isMobileAppModalOpen, this.setMobileAppModalIsOpen, "low", MobileAppModal)} + {this.renderModal( + isLayoutModalOpen, + this.setLayoutModalIsOpen, + 'low', + LayoutModalContainer, + )} + ); } diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/options-dropdown/container.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/options-dropdown/container.jsx index 8f0ded11b3..60c2e81627 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/options-dropdown/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/options-dropdown/container.jsx @@ -1,30 +1,26 @@ -import React from 'react'; -import { useContext } from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; +import React, { useContext } from 'react'; import deviceInfo from '/imports/utils/deviceInfo'; import browserInfo from '/imports/utils/browserInfo'; import OptionsDropdown from './component'; import FullscreenService from '/imports/ui/components/common/fullscreen-button/service'; -import { meetingIsBreakout } from '/imports/ui/components/app/service'; -import { layoutSelectInput, layoutSelect } from '../../layout/context'; -import { SMALL_VIEWPORT_BREAKPOINT } from '../../layout/enums'; +import { layoutSelect } from '../../layout/context'; import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; import { USER_LEAVE_MEETING } from '/imports/ui/core/graphql/mutations/userMutations'; import { useMutation } from '@apollo/client'; import useMeeting from '/imports/ui/core/hooks/useMeeting'; import { useShortcut } from '/imports/ui/core/hooks/useShortcut'; +import { useStorageKey } from '/imports/ui/services/storage/hooks'; +import Session from '/imports/ui/services/storage/in-memory'; +import { useIsLayoutsEnabled } from '/imports/ui/services/features'; const { isIphone } = deviceInfo; const { isSafari, isValidSafariVersion } = browserInfo; const noIOSFullscreen = !!(((isSafari && !isValidSafariVersion) || isIphone)); -const getAudioCaptions = () => Session.get('audioCaptions') || false; -const setAudioCaptions = (value) => Session.set('audioCaptions', value); +const setAudioCaptions = (value) => Session.setItem('audioCaptions', value); const OptionsDropdownContainer = (props) => { - const { width: browserWidth } = layoutSelectInput((i) => i.browser); - const isMobile = browserWidth <= SMALL_VIEWPORT_BREAKPOINT; const isRTL = layoutSelect((i) => i.isRTL); const { pluginsExtensibleAreasAggregatedState } = useContext(PluginsContext); let optionsDropdownItems = []; @@ -36,43 +32,41 @@ const OptionsDropdownContainer = (props) => { const { data: currentMeeting, - } = useMeeting((m) => { - return { - componentsFlags: m.componentsFlags, - }; - }); + } = useMeeting((m) => ({ + componentsFlags: m.componentsFlags, + isBreakout: m.isBreakout, + })); const componentsFlags = currentMeeting?.componentsFlags; const audioCaptionsEnabled = componentsFlags?.hasCaption; const [userLeaveMeeting] = useMutation(USER_LEAVE_MEETING); const openOptions = useShortcut('openOptions'); + const audioCaptionsActive = useStorageKey('audioCaptions') || false; + const isDropdownOpen = useStorageKey('dropdownOpen'); + const isLayoutsEnabled = useIsLayoutsEnabled(); return ( setAudioCaptions(value), + isMobile: deviceInfo.isMobile, + noIOSFullscreen, + isBreakoutRoom: currentMeeting?.isBreakout, + // TODO: Replace/Remove + isMeteorConnected: true, + isLayoutsEnabled, ...props, }} /> ); }; -export default withTracker((props) => { - const handleToggleFullscreen = () => FullscreenService.toggleFullScreen(); - return { - amIModerator: props.amIModerator, - audioCaptionsActive: getAudioCaptions(), - audioCaptionsSet: (value) => setAudioCaptions(value), - isMobile: deviceInfo.isMobile, - handleToggleFullscreen, - noIOSFullscreen, - isMeteorConnected: Meteor.status().connected, - isBreakoutRoom: meetingIsBreakout(), - isDropdownOpen: Session.get('dropdownOpen'), - }; -})(OptionsDropdownContainer); +export default OptionsDropdownContainer; diff --git a/bigbluebutton-html5/imports/ui/components/notes/component.tsx b/bigbluebutton-html5/imports/ui/components/notes/component.tsx index 72c8d42fae..9d57f63329 100644 --- a/bigbluebutton-html5/imports/ui/components/notes/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/notes/component.tsx @@ -1,8 +1,7 @@ import React, { useEffect, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { useMutation, useSubscription } from '@apollo/client'; +import { useMutation } from '@apollo/client'; import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component'; -import NotesService from '/imports/ui/components/notes/service'; import PadContainer from '/imports/ui/components/pads/pads-graphql/component'; import browserInfo from '/imports/utils/browserInfo'; import Header from '/imports/ui/components/common/control-header/component'; @@ -19,11 +18,11 @@ import { PIN_NOTES } from './mutations'; import { EXTERNAL_VIDEO_STOP } from '/imports/ui/components/external-video-player/mutations'; import { screenshareHasEnded, - isScreenBroadcasting, + useIsScreenBroadcasting, } from '/imports/ui/components/screenshare/service'; - -const NOTES_CONFIG = window.meetingClientSettings.public.notes; -const DELAY_UNMOUNT_SHARED_NOTES = window.meetingClientSettings.public.app.delayForUnmountOfSharedNote; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; +import { useIsPresentationEnabled } from '../../services/features'; +import { useStorageKey } from '/imports/ui/services/storage/hooks'; const intlMessages = defineMessages({ hide: { @@ -58,9 +57,10 @@ interface NotesGraphqlProps extends NotesContainerGraphqlProps { isRTL: boolean; shouldShowSharedNotesOnPresentationArea: boolean; handlePinSharedNotes: (pinned: boolean) => void; + isPresentationEnabled: boolean; } -let timoutRef: NodeJS.Timeout | undefined; +let timoutRef: ReturnType; const sidebarContentToIgnoreDelay = ['captions']; const NotesGraphql: React.FC = (props) => { @@ -76,6 +76,7 @@ const NotesGraphql: React.FC = (props) => { isToSharedNotesBeShow, shouldShowSharedNotesOnPresentationArea, handlePinSharedNotes, + isPresentationEnabled, } = props; const [shouldRenderNotes, setShouldRenderNotes] = useState(false); const intl = useIntl(); @@ -96,6 +97,9 @@ const NotesGraphql: React.FC = (props) => { style.padding = 0; style.display = 'none'; } + + const DELAY_UNMOUNT_SHARED_NOTES = window.meetingClientSettings.public.app.delayForUnmountOfSharedNote; + useEffect(() => { if (isToSharedNotesBeShow) { setShouldRenderNotes(true); @@ -126,6 +130,8 @@ const NotesGraphql: React.FC = (props) => { ) : null; }; + const NOTES_CONFIG = window.meetingClientSettings.public.notes; + return (shouldRenderNotes || shouldShowSharedNotesOnPresentationArea) && ( = (props) => { label: intl.formatMessage(intlMessages.title), }} customRightButton={ - + } /> ) : renderHeaderOnMedia()} = (props) => { const { area, isToSharedNotesBeShow } = props; const hasPermission = useHasPermission(); - const { data: pinnedPadData } = useSubscription(PINNED_PAD_SUBSCRIPTION); + const { data: pinnedPadData } = useDeduplicatedSubscription(PINNED_PAD_SUBSCRIPTION); const { data: currentUserData } = useCurrentUser((user) => ({ presenter: user.presenter, })); @@ -185,16 +191,24 @@ const NotesContainerGraphql: React.FC = (props) => { const layoutContextDispatch = layoutDispatch(); const amIPresenter = !!currentUserData?.presenter; + const NOTES_CONFIG = window.meetingClientSettings.public.notes; + const isRTL = document.documentElement.getAttribute('dir') === 'rtl'; - const shouldShowSharedNotesOnPresentationArea = !!pinnedPadData + const { isOpen: isSidebarContentOpen } = sidebarContent; + const isGridLayout = useStorageKey('isGridEnabled'); + + const shouldShowSharedNotesOnPresentationArea = isGridLayout ? !!pinnedPadData + && pinnedPadData.sharedNotes[0]?.sharedNotesExtId === NOTES_CONFIG.id && isSidebarContentOpen : !!pinnedPadData && pinnedPadData.sharedNotes[0]?.sharedNotesExtId === NOTES_CONFIG.id; const [stopExternalVideoShare] = useMutation(EXTERNAL_VIDEO_STOP); + const isScreenBroadcasting = useIsScreenBroadcasting(); + const isPresentationEnabled = useIsPresentationEnabled(); const handlePinSharedNotes = (pinned: boolean) => { if (pinned) { stopExternalVideoShare(); - if (isScreenBroadcasting()) screenshareHasEnded(); + if (isScreenBroadcasting) screenshareHasEnded(); } pinSharedNotes({ variables: { pinned } }); }; @@ -212,6 +226,7 @@ const NotesContainerGraphql: React.FC = (props) => { isRTL={isRTL} isToSharedNotesBeShow={isToSharedNotesBeShow} handlePinSharedNotes={handlePinSharedNotes} + isPresentationEnabled={isPresentationEnabled} /> ); }; diff --git a/bigbluebutton-html5/imports/ui/components/notes/hooks/useHasPermission.ts b/bigbluebutton-html5/imports/ui/components/notes/hooks/useHasPermission.ts index db631c35ab..dd8054ffde 100644 --- a/bigbluebutton-html5/imports/ui/components/notes/hooks/useHasPermission.ts +++ b/bigbluebutton-html5/imports/ui/components/notes/hooks/useHasPermission.ts @@ -1,8 +1,6 @@ import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; import useMeeting from '/imports/ui/core/hooks/useMeeting'; -const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; - const useHasPermission = () => { const { data: currentUserData } = useCurrentUser((u) => ({ locked: u.locked, @@ -12,6 +10,8 @@ const useHasPermission = () => { lockSettings: m.lockSettings, })); + const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; + if (currentUserData?.role === ROLE_MODERATOR) return true; if (currentUserData?.locked) { diff --git a/bigbluebutton-html5/imports/ui/components/notes/hooks/useHasUnreadNotes.ts b/bigbluebutton-html5/imports/ui/components/notes/hooks/useHasUnreadNotes.ts index 9bb1306813..8295dc4de9 100644 --- a/bigbluebutton-html5/imports/ui/components/notes/hooks/useHasUnreadNotes.ts +++ b/bigbluebutton-html5/imports/ui/components/notes/hooks/useHasUnreadNotes.ts @@ -1,9 +1,9 @@ import useRev from '/imports/ui/components/pads/pads-graphql/hooks/useRev'; import useNotesLastRev from './useNotesLastRev'; -const NOTES_CONFIG = window.meetingClientSettings.public.notes; - const useHasUnreadNotes = () => { + const NOTES_CONFIG = window.meetingClientSettings.public.notes; + const { lastRev } = useNotesLastRev(); const rev = useRev(NOTES_CONFIG.id); return rev > lastRev; diff --git a/bigbluebutton-html5/imports/ui/components/notes/notes-dropdown/component.tsx b/bigbluebutton-html5/imports/ui/components/notes/notes-dropdown/component.tsx index eddbb4c74d..d8a3fecc40 100644 --- a/bigbluebutton-html5/imports/ui/components/notes/notes-dropdown/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/notes/notes-dropdown/component.tsx @@ -1,19 +1,17 @@ import React, { useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { useQuery, useSubscription } from '@apollo/client'; +import { useQuery } from '@apollo/client'; import BBBMenu from '/imports/ui/components/common/menu/component'; import Trigger from '/imports/ui/components/common/control-header/right/component'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; -import NotesService from '/imports/ui/components/notes/service'; import { uniqueId } from '/imports/utils/string-utils'; import { layoutSelect } from '/imports/ui/components/layout/context'; import { PROCESSED_PRESENTATIONS_SUBSCRIPTION } from '/imports/ui/components/whiteboard/queries'; import Service from './service'; import { GET_PAD_ID, GetPadIdQueryResponse } from './queries'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const DEBOUNCE_TIMEOUT = 15000; -const NOTES_CONFIG = window.meetingClientSettings.public.notes; -const NOTES_IS_PINNABLE = NOTES_CONFIG.pinnable; const intlMessages = defineMessages({ convertAndUploadLabel: { @@ -31,7 +29,8 @@ const intlMessages = defineMessages({ }); interface NotesDropdownContainerGraphqlProps { - handlePinSharedNotes: (pinned: boolean) => void + handlePinSharedNotes: (pinned: boolean) => void; + presentationEnabled: boolean; } interface NotesDropdownGraphqlProps extends NotesDropdownContainerGraphqlProps { @@ -44,10 +43,11 @@ interface NotesDropdownGraphqlProps extends NotesDropdownContainerGraphqlProps { const NotesDropdownGraphql: React.FC = (props) => { const { - amIPresenter, presentations, handlePinSharedNotes, isRTL, padId, + amIPresenter, presentations, handlePinSharedNotes, isRTL, padId, presentationEnabled, } = props; const [converterButtonDisabled, setConverterButtonDisabled] = useState(false); const intl = useIntl(); + const NOTES_IS_PINNABLE = window.meetingClientSettings.public.notes.pinnable; const getAvailableActions = () => { const uploadIcon = 'upload'; @@ -66,7 +66,7 @@ const NotesDropdownGraphql: React.FC = (props) => { onClick: () => { setConverterButtonDisabled(true); setTimeout(() => setConverterButtonDisabled(false), DEBOUNCE_TIMEOUT); - return Service.convertAndUpload(presentations, padId); + return Service.convertAndUpload(presentations, padId, presentationEnabled); }, }, ); @@ -122,7 +122,7 @@ const NotesDropdownGraphql: React.FC = (props) => { }; const NotesDropdownContainerGraphql: React.FC = (props) => { - const { handlePinSharedNotes } = props; + const { handlePinSharedNotes, presentationEnabled } = props; const { data: currentUserData } = useCurrentUser((user) => ({ presenter: user.presenter, })); @@ -130,12 +130,14 @@ const NotesDropdownContainerGraphql: React.FC i.isRTL); - const { data: presentationData } = useSubscription(PROCESSED_PRESENTATIONS_SUBSCRIPTION); + const { data: presentationData } = useDeduplicatedSubscription(PROCESSED_PRESENTATIONS_SUBSCRIPTION); const presentations = presentationData?.pres_presentation || []; + const NOTES_CONFIG = window.meetingClientSettings.public.notes; + const { data: padIdData } = useQuery( GET_PAD_ID, - { variables: { externalId: NotesService.ID } }, + { variables: { externalId: NOTES_CONFIG.id } }, ); const padId = padIdData?.sharedNotes?.[0]?.padId; @@ -147,6 +149,7 @@ const NotesDropdownContainerGraphql: React.FC ); diff --git a/bigbluebutton-html5/imports/ui/components/notes/notes-dropdown/service.ts b/bigbluebutton-html5/imports/ui/components/notes/notes-dropdown/service.ts index 71cd83b47c..6662fbe49a 100644 --- a/bigbluebutton-html5/imports/ui/components/notes/notes-dropdown/service.ts +++ b/bigbluebutton-html5/imports/ui/components/notes/notes-dropdown/service.ts @@ -1,13 +1,9 @@ import Auth from '/imports/ui/services/auth'; import PresentationUploaderService from '/imports/ui/components/presentation/presentation-uploader/service'; import PadsService from '/imports/ui/components/pads/pads-graphql/service'; -import { UploadingPresentations } from '/imports/api/presentations'; -import { uniqueId } from '/imports/utils/string-utils'; - -const PADS_CONFIG = window.meetingClientSettings.public.pads; // eslint-disable-next-line @typescript-eslint/no-explicit-any -async function convertAndUpload(presentations: any, padId: string) { +async function convertAndUpload(presentations: any, padId: string, presentationEnabled = true) { let filename = 'Shared_Notes'; const duplicates = presentations.filter( // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -20,17 +16,7 @@ async function convertAndUpload(presentations: any, padId: string) { const extension = 'pdf'; filename = `${filename}.${extension}`; - UploadingPresentations.insert({ - id: uniqueId(filename), - progress: 0, - filename, - lastModifiedUploader: false, - upload: { - done: false, - error: false, - }, - uploadTimestamp: new Date(), - }); + const PADS_CONFIG = window.meetingClientSettings.public.pads; const exportUrl = Auth.authenticateURL(`${PADS_CONFIG.url}/p/${padId}/export/${extension}?${params}`); const sharedNotesAsFile = await fetch(exportUrl, { credentials: 'include' }); @@ -54,7 +40,7 @@ async function convertAndUpload(presentations: any, padId: string) { onUpload: () => { }, onProgress: () => { }, onDone: () => { }, - }); + }, undefined, undefined, undefined, presentationEnabled); } export default { diff --git a/bigbluebutton-html5/imports/ui/components/notes/service.ts b/bigbluebutton-html5/imports/ui/components/notes/service.ts index cfab308565..3d61325ca1 100644 --- a/bigbluebutton-html5/imports/ui/components/notes/service.ts +++ b/bigbluebutton-html5/imports/ui/components/notes/service.ts @@ -1,9 +1,7 @@ import { ACTIONS, PANELS } from '/imports/ui/components/layout/enums'; -import { isSharedNotesEnabled } from '/imports/ui/services/features'; +import { useIsSharedNotesEnabled } from '/imports/ui/services/features'; -const NOTES_CONFIG = window.meetingClientSettings.public.notes; - -const isEnabled = () => isSharedNotesEnabled(); +const useIsEnabled = () => useIsSharedNotesEnabled(); // @ts-ignore Until everything in Typescript const toggleNotesPanel = (sidebarContentPanel, layoutContextDispatch) => { @@ -21,7 +19,6 @@ const toggleNotesPanel = (sidebarContentPanel, layoutContextDispatch) => { }; export default { - ID: NOTES_CONFIG.id, toggleNotesPanel, - isEnabled, + useIsEnabled, }; diff --git a/bigbluebutton-html5/imports/ui/components/notifications-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/notifications-bar/component.jsx index c1392be242..6ef7afffc8 100644 --- a/bigbluebutton-html5/imports/ui/components/notifications-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/notifications-bar/component.jsx @@ -11,17 +11,11 @@ const propTypes = { color: PropTypes.string, }; -const defaultProps = { - color: 'default', -}; - -const NotificationsBar = (props) => { - const { - color, - children, - alert, - } = props; - +const NotificationsBar = ({ + color = 'default', + children, + alert, +}) => { const hasColor = COLORS.includes(color); return ( @@ -42,6 +36,5 @@ const NotificationsBar = (props) => { }; NotificationsBar.propTypes = propTypes; -NotificationsBar.defaultProps = defaultProps; export default injectWbResizeEvent(NotificationsBar); diff --git a/bigbluebutton-html5/imports/ui/components/notifications-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/notifications-bar/container.jsx index 03e93a9e1a..b89fcda700 100644 --- a/bigbluebutton-html5/imports/ui/components/notifications-bar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/notifications-bar/container.jsx @@ -1,164 +1,78 @@ -import { Meteor } from 'meteor/meteor'; -import { withTracker } from 'meteor/react-meteor-data'; import React, { useEffect } from 'react'; -import { defineMessages, injectIntl } from 'react-intl'; -import Auth from '/imports/ui/services/auth'; -import Meetings from '/imports/api/meetings'; +import { defineMessages, useIntl } from 'react-intl'; import { isEmpty } from 'radash'; import MeetingRemainingTime from '/imports/ui/components/common/remaining-time/meeting-duration/component'; -import Styled from './styles'; +import { useReactiveVar } from '@apollo/client'; import { layoutSelectInput, layoutDispatch } from '../layout/context'; import { ACTIONS } from '../layout/enums'; import NotificationsBar from './component'; - -// disconnected and trying to open a new connection -const STATUS_CONNECTING = 'connecting'; - -// permanently failed to connect; e.g., the client and server support different versions of DDP -const STATUS_FAILED = 'failed'; - -// failed to connect and waiting to try to reconnect -const STATUS_WAITING = 'waiting'; +import connectionStatus from '../../core/graphql/singletons/connectionStatus'; +import useMeeting from '../../core/hooks/useMeeting'; const intlMessages = defineMessages({ - failedMessage: { - id: 'app.failedMessage', - description: 'Notification for connecting to server problems', + connectionCode3001: { + id: 'app.notificationBar.connectionCode3001', + description: 'Closed connection alert', }, - connectingMessage: { - id: 'app.connectingMessage', - description: 'Notification message for when client is connecting to server', + connectionCode3002: { + id: 'app.notificationBar.connectionCode3002', + description: 'Impossible connection alert', }, - waitingMessage: { - id: 'app.waitingMessage', - description: 'Notification message for disconnection with reconnection counter', + connectionCode3003: { + id: 'app.notificationBar.connectionCode3003', + description: 'Unresponsive server alert', }, - retryNow: { - id: 'app.retryNow', - description: 'Retry now text for reconnection counter', + connectionCode3004: { + id: 'app.notificationBar.connectionCode3004', + description: 'Unstable connection alert', }, - calculatingBreakoutTimeRemaining: { - id: 'app.calculatingBreakoutTimeRemaining', - description: 'Message that tells that the remaining time is being calculated', - }, - alertMeetingEndsUnderMinutes: { - id: 'app.meeting.alertMeetingEndsUnderMinutes', - description: 'Alert that tells that the meeting ends under x minutes', - }, - alertBreakoutEndsUnderMinutes: { - id: 'app.meeting.alertBreakoutEndsUnderMinutes', - description: 'Alert that tells that the breakout ends under x minutes', + connectionCode3005: { + id: 'app.notificationBar.connectionCode3005', + description: 'Slow data alert', }, }); -const NotificationsBarContainer = (props) => { - const { message, color } = props; +const STATUS_CRITICAL = 'critical'; +const COLOR_PRIMARY = 'primary'; - const notificationsBar = layoutSelectInput((i) => i.notificationsBar); - const layoutContextDispatch = layoutDispatch(); - - const { hasNotification } = notificationsBar; - - useEffect(() => { - const localHasNotification = !!message; - - if (localHasNotification !== hasNotification) { - layoutContextDispatch({ - type: ACTIONS.SET_HAS_NOTIFICATIONS_BAR, - value: localHasNotification, - }); - } - }, [message, hasNotification]); - - if (isEmpty(message)) { - return null; - } - - return ( - - {message} - - ); -}; - -let retrySeconds = 0; -const retrySecondsDep = new Tracker.Dependency(); -let retryInterval = null; - -const getRetrySeconds = () => { - retrySecondsDep.depend(); - return retrySeconds; -}; - -const setRetrySeconds = (sec = 0) => { - if (sec !== retrySeconds) { - retrySeconds = sec; - retrySecondsDep.changed(); - } -}; - -const startCounter = (sec, set, get, interval) => { - clearInterval(interval); - set(sec); - return setInterval(() => { - set(get() - 1); - }, 1000); -}; - -const reconnect = () => { - Meteor.reconnect(); -}; - -export default injectIntl(withTracker(({ intl }) => { - const { status, connected, retryTime } = Meteor.status(); +const NotificationsBarContainer = () => { const data = {}; - + data.alert = true; + data.color = COLOR_PRIMARY; + const intl = useIntl(); + const connected = useReactiveVar(connectionStatus.getConnectedStatusVar()); + const serverIsResponding = useReactiveVar(connectionStatus.getServerIsRespondingVar()); + const pingIsComing = useReactiveVar(connectionStatus.getPingIsComingVar()); + const lastRttRequestSuccess = useReactiveVar(connectionStatus.getLastRttRequestSuccessVar()); + const rttStatus = useReactiveVar(connectionStatus.getRttStatusVar()); + const isCritical = rttStatus === STATUS_CRITICAL; + // if connection failed x attempts a error will be thrown if (!connected) { - data.color = 'primary'; - switch (status) { - case STATUS_FAILED: { - data.color = 'danger'; - data.message = intl.formatMessage(intlMessages.failedMessage); - break; - } - case STATUS_CONNECTING: { - data.message = intl.formatMessage(intlMessages.connectingMessage); - break; - } - case STATUS_WAITING: { - const sec = Math.round((retryTime - (new Date()).getTime()) / 1000); - retryInterval = startCounter(sec, setRetrySeconds, getRetrySeconds, retryInterval); - data.message = ( - <> - {intl.formatMessage(intlMessages.waitingMessage, { 0: getRetrySeconds() })} - - {intl.formatMessage(intlMessages.retryNow)} - - - ); - break; - } - default: - break; - } - - return data; + data.message = isCritical + ? intl.formatMessage(intlMessages.connectionCode3002) + : intl.formatMessage(intlMessages.connectionCode3001); + } else if (connected && !serverIsResponding) { + data.message = isCritical + ? intl.formatMessage(intlMessages.connectionCode3004) + : intl.formatMessage(intlMessages.connectionCode3003); + } else if (connected && serverIsResponding && !pingIsComing && lastRttRequestSuccess) { + data.message = intl.formatMessage(intlMessages.connectionCode3005); } - const meetingId = Auth.meetingID; + const { data: meeting } = useMeeting((m) => ({ + isBreakout: m.isBreakout, + componentsFlags: m.componentsFlags, + })); - const Meeting = Meetings.findOne({ meetingId }, - { fields: { isBreakout: 1, componentsFlags: 1 } }); - - if (Meeting.isBreakout) { + if (meeting?.isBreakout) { data.message = ( ); } - if (Meeting) { - const { isBreakout, componentsFlags } = Meeting; + if (meeting) { + const { isBreakout, componentsFlags } = meeting; if (componentsFlags.showRemainingTime && !isBreakout) { data.message = ( @@ -167,7 +81,31 @@ export default injectIntl(withTracker(({ intl }) => { } } - data.alert = true; - data.color = 'primary'; - return data; -})(NotificationsBarContainer)); + const notificationsBar = layoutSelectInput((i) => i.notificationsBar); + const layoutContextDispatch = layoutDispatch(); + + const { hasNotification } = notificationsBar; + + useEffect(() => { + const localHasNotification = !!data.message; + + if (localHasNotification !== hasNotification) { + layoutContextDispatch({ + type: ACTIONS.SET_HAS_NOTIFICATIONS_BAR, + value: localHasNotification, + }); + } + }, [data.message, hasNotification]); + + if (isEmpty(data.message)) { + return null; + } + + return ( + + {data.message} + + ); +}; + +export default NotificationsBarContainer; diff --git a/bigbluebutton-html5/imports/ui/components/notifications/component.tsx b/bigbluebutton-html5/imports/ui/components/notifications/component.tsx index 4fe5f4d193..8a0921948e 100644 --- a/bigbluebutton-html5/imports/ui/components/notifications/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/notifications/component.tsx @@ -1,4 +1,3 @@ -import { useSubscription } from '@apollo/client'; import React, { useEffect } from 'react'; import { FormattedMessage } from 'react-intl'; import { Notification, NotificationResponse, getNotificationsStream } from './queries'; @@ -11,6 +10,8 @@ import { userJoinPushAlert, userLeavePushAlert, } from './service'; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const Notifications: React.FC = () => { const [registeredAt, setRegisteredAt] = React.useState(new Date().toISOString()); @@ -35,10 +36,31 @@ const Notifications: React.FC = () => { isModerator: u.isModerator, })); + const Settings = getSettingsSingletonInstance(); + const { + userJoinPushAlerts, + userLeavePushAlerts, + guestWaitingPushAlerts, + } = Settings.application; + + const excludedMessageIds = []; + + if (!userJoinPushAlerts) { + excludedMessageIds.push('app.notification.userJoinPushAlert'); + } + + if (!userLeavePushAlerts) { + excludedMessageIds.push('app.notification.userLeavePushAlert'); + } + + if (!guestWaitingPushAlerts) { + excludedMessageIds.push('app.userList.guest.pendingGuestAlert'); + } + const { data: notificationsStream, - } = useSubscription(getNotificationsStream, { - variables: { initialCursor: '2024-04-18' }, + } = useDeduplicatedSubscription(getNotificationsStream, { + variables: { initialCursor: '2024-04-18', excludedMessageIds }, }); const notifier = (notification: Notification) => { diff --git a/bigbluebutton-html5/imports/ui/components/notifications/queries.ts b/bigbluebutton-html5/imports/ui/components/notifications/queries.ts index b76c8501a8..692039dcb4 100644 --- a/bigbluebutton-html5/imports/ui/components/notifications/queries.ts +++ b/bigbluebutton-html5/imports/ui/components/notifications/queries.ts @@ -16,8 +16,15 @@ export interface NotificationResponse { } export const getNotificationsStream = gql` - subscription getNotificationStream($initialCursor: timestamptz!){ - notification_stream(batch_size: 10, cursor: {initial_value: {createdAt: $initialCursor}}) { + subscription getNotificationStream( + $initialCursor: timestamptz!, + $excludedMessageIds: [String!]! + ){ + notification_stream( + batch_size: 10, + cursor: {initial_value: {createdAt: $initialCursor}}, + where: {messageId: {_nin: $excludedMessageIds}} + ) { notificationType icon messageId diff --git a/bigbluebutton-html5/imports/ui/components/notifications/service.ts b/bigbluebutton-html5/imports/ui/components/notifications/service.ts index f1b88b841e..253982de52 100644 --- a/bigbluebutton-html5/imports/ui/components/notifications/service.ts +++ b/bigbluebutton-html5/imports/ui/components/notifications/service.ts @@ -1,11 +1,8 @@ import { makeVar } from '@apollo/client'; import { Notification } from './queries'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import { throttle } from '/imports/utils/throttle'; -const CDN = window.meetingClientSettings.public.app.cdn; -const BASENAME = window.meetingClientSettings.public.app.basename; -const HOST = CDN + BASENAME; const GUEST_WAITING_BELL_THROTTLE_TIME = 10000; const lastLayoutUpdateNotification = makeVar(new Date().getTime()); @@ -24,8 +21,13 @@ export const NotifyPublishedPoll = ( }; function ringGuestWaitingBell() { + const Settings = getSettingsSingletonInstance(); // @ts-ignore - JS code if (Settings.application.guestWaitingAudioAlerts) { + const CDN = window.meetingClientSettings.public.app.cdn; + const BASENAME = window.meetingClientSettings.public.app.basename; + const HOST = CDN + BASENAME; + const audio = new Audio(`${HOST}/resources/sounds/doorbell.mp3`); audio.play(); } @@ -41,6 +43,7 @@ export const pendingGuestAlert = ( notification: Notification, notifier: (notification: Notification) => void, ) => { + const Settings = getSettingsSingletonInstance(); // @ts-ignore - JS code if (Settings.application.guestWaitingPushAlerts) { notifier(notification); @@ -53,6 +56,7 @@ export const userJoinPushAlert = ( notification: Notification, notifier: (notification: Notification) => void, ) => { + const Settings = getSettingsSingletonInstance(); const { userJoinAudioAlerts, userJoinPushAlerts, @@ -63,8 +67,7 @@ export const userJoinPushAlert = ( if (userJoinAudioAlerts) { new Audio(`${window.meetingClientSettings.public.app.cdn - + window.meetingClientSettings.public.app.basename - + window.meetingClientSettings.public.app.instanceId}` + + window.meetingClientSettings.public.app.basename}` + '/resources/sounds/userJoin.mp3').play(); } @@ -77,6 +80,7 @@ export const userLeavePushAlert = ( notification: Notification, notifier: (notification: Notification) => void, ) => { + const Settings = getSettingsSingletonInstance(); const { userLeaveAudioAlerts, userLeavePushAlerts, @@ -87,8 +91,7 @@ export const userLeavePushAlert = ( if (userLeaveAudioAlerts) { new Audio(`${window.meetingClientSettings.public.app.cdn - + window.meetingClientSettings.public.app.basename - + window.meetingClientSettings.public.app.instanceId}` + + window.meetingClientSettings.public.app.basename}` + '/resources/sounds/userJoin.mp3').play(); } diff --git a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/component.tsx b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/component.tsx index 0990ca3ea9..f0388158d5 100644 --- a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/component.tsx @@ -1,12 +1,13 @@ import React, { useEffect, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { useMutation, useSubscription } from '@apollo/client'; +import { useMutation } from '@apollo/client'; import { HAS_PAD_SUBSCRIPTION, HasPadSubscriptionResponse } from './queries'; import { PAD_SESSION_SUBSCRIPTION, PadSessionSubscriptionResponse } from './sessions/queries'; import { CREATE_SESSION } from './mutations'; import Service from './service'; import Styled from './styles'; import PadContent from './content/component'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const intlMessages = defineMessages({ hint: { @@ -80,11 +81,13 @@ const PadContainerGraphql: React.FC = (props) => { isResizing, } = props; - const { data: hasPadData } = useSubscription( + const { data: hasPadData } = useDeduplicatedSubscription( HAS_PAD_SUBSCRIPTION, { variables: { externalId } }, ); - const { data: padSessionData } = useSubscription(PAD_SESSION_SUBSCRIPTION); + const { data: padSessionData } = useDeduplicatedSubscription( + PAD_SESSION_SUBSCRIPTION, + ); const [createSession] = useMutation(CREATE_SESSION); const sessionData = padSessionData?.sharedNotes_session ?? []; diff --git a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/content/component.tsx b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/content/component.tsx index 508101c38d..e67c2b3f33 100644 --- a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/content/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/content/component.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useState } from 'react'; -import { useSubscription } from '@apollo/client'; import { patch } from '@mconf/bbb-diff'; import Styled from './styles'; import { GET_PAD_CONTENT_DIFF_STREAM, GetPadContentDiffStreamResponse } from './queries'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; interface PadContentProps { content: string; @@ -38,7 +38,7 @@ const PadContent: React.FC = ({ const PadContentContainer: React.FC = ({ externalId }) => { const [content, setContent] = useState(''); - const { data: contentDiffData } = useSubscription( + const { data: contentDiffData } = useDeduplicatedSubscription( GET_PAD_CONTENT_DIFF_STREAM, { variables: { externalId } }, ); diff --git a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/hooks/useRev.ts b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/hooks/useRev.ts index 27bceca530..845dcb4026 100644 --- a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/hooks/useRev.ts +++ b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/hooks/useRev.ts @@ -1,5 +1,6 @@ -import { gql, useSubscription } from '@apollo/client'; +import { gql } from '@apollo/client'; import { useEffect, useState } from 'react'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; interface GetPadLastRevResponse { sharedNotes: Array<{ @@ -19,7 +20,7 @@ const GET_PAD_LAST_REV = gql` const useRev = (externalId: string) => { const [rev, setRev] = useState(0); - const { data: padRevData } = useSubscription( + const { data: padRevData } = useDeduplicatedSubscription( GET_PAD_LAST_REV, { variables: { externalId } }, ); diff --git a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/service.ts b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/service.ts index aa4da7b0e8..9e4602eb64 100644 --- a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/service.ts +++ b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/service.ts @@ -1,9 +1,8 @@ import Auth from '/imports/ui/services/auth'; -import Settings from '/imports/ui/services/settings'; - -const PADS_CONFIG = window.meetingClientSettings.public.pads; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const getLang = (): string => { + const Settings = getSettingsSingletonInstance(); // @ts-ignore While Meteor in the project const { locale } = Settings.application; return locale ? locale.toLowerCase() : ''; @@ -22,6 +21,8 @@ const getParams = () => { }; const buildPadURL = (padId: string, sessionIds: Array) => { + const PADS_CONFIG = window.meetingClientSettings.public.pads; + const params = getParams(); const sessionIdsStr = sessionIds.join(','); const url = Auth.authenticateURL( diff --git a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/sessions/component.tsx b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/sessions/component.tsx index d255f002b5..dd7e994faf 100644 --- a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/sessions/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/sessions/component.tsx @@ -1,9 +1,11 @@ -import { useSubscription } from '@apollo/client'; import { PAD_SESSION_SUBSCRIPTION, PadSessionSubscriptionResponse } from './queries'; import Service from './service'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const PadSessionContainerGraphql = () => { - const { data: padSessionData } = useSubscription(PAD_SESSION_SUBSCRIPTION); + const { data: padSessionData } = useDeduplicatedSubscription( + PAD_SESSION_SUBSCRIPTION, + ); if (padSessionData) { const sessions = new Set(); diff --git a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/sessions/service.ts b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/sessions/service.ts index 4bb941146b..edefbac88c 100644 --- a/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/sessions/service.ts +++ b/bigbluebutton-html5/imports/ui/components/pads/pads-graphql/sessions/service.ts @@ -1,9 +1,9 @@ -const COOKIE_CONFIG = window.meetingClientSettings.public.pads.cookie; -const PATH = COOKIE_CONFIG.path; -const SAME_SITE = COOKIE_CONFIG.sameSite; -const SECURE = COOKIE_CONFIG.secure; - const setCookie = (sessions: Array) => { + const COOKIE_CONFIG = window.meetingClientSettings.public.pads.cookie; + const PATH = COOKIE_CONFIG.path; + const SAME_SITE = COOKIE_CONFIG.sameSite; + const SECURE = COOKIE_CONFIG.secure; + const sessionIds = sessions.join(','); document.cookie = `sessionID=${sessionIds}; path=${PATH}; SameSite=${SAME_SITE}; ${SECURE ? 'Secure' : ''}`; }; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/channel-manager/reader-manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/channel-manager/reader-manager.tsx index 6929683b30..faddf4a13f 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/channel-manager/reader-manager.tsx +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/channel-manager/reader-manager.tsx @@ -1,12 +1,15 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { DocumentNode } from 'graphql'; -import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; -import { GraphqlResponseWrapper, UpdatedEventDetails } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/types'; +import { + GraphqlResponseWrapper, HookEventWrapper, SubscribedEventDetails, UpdatedEventDetails, +} from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/types'; import { DataChannelHooks, DataChannelTypes } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-channel/enums'; -import { PLUGIN_DATA_CHANNEL_LATEST_ITEM, PLUGIN_DATA_CHANNEL_NEW_ITEMS, PLUGIN_DATA_CHANNEL_All_ITEMS } from '../subscriptions'; import createUseSubscription from '/imports/ui/core/hooks/createUseSubscription'; +import { HookEvents } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/enum'; +import { DataChannelArguments } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-channel/types'; +import { PLUGIN_DATA_CHANNEL_LATEST_ITEM, PLUGIN_DATA_CHANNEL_NEW_ITEMS, PLUGIN_DATA_CHANNEL_All_ITEMS } from '../subscriptions'; export interface DataChannelItemManagerReaderProps { pluginName: string; @@ -16,14 +19,6 @@ export interface DataChannelItemManagerReaderProps { dataChannelIdentifier: string; } -export interface MutationVariables { - pluginName: string, - dataChannel: string, - payloadJson: string, - toRoles: PluginSdk.DataChannelPushEntryFunctionUserRole[], - toUserIds: string[], -} - export interface SubscriptionVariables { subChannelName: string; pluginName: string; @@ -41,6 +36,7 @@ export const DataChannelItemManagerReader: React.ElementType(false); const cursor = useRef(new Date()); let subscription: DocumentNode; const variables: SubscriptionVariables = { @@ -70,6 +66,30 @@ export const DataChannelItemManagerReader: React.ElementType(subscription, variables, usePatchedSubscription)((obj) => obj); + useEffect(() => { + const subscribeHandler: EventListener = ( + (event: HookEventWrapper) => { + if (event.detail.hook === DataChannelHooks.DATA_CHANNEL_BUILDER) { + const eventDetails = event.detail as SubscribedEventDetails; + const hookArguments = eventDetails?.hookArguments as DataChannelArguments; + const dataChannelTypeFromEvent = hookArguments.dataChannelType!; + if (hookArguments?.channelName && hookArguments?.pluginName + && hookArguments.subChannelName === subChannelName + && hookArguments.pluginName === pluginName + && hookArguments.channelName === channelName + && dataChannelTypeFromEvent === dataChannelType + ) { + setSendSignal((signal) => !signal); + } + } + }) as EventListener; + + window.addEventListener(HookEvents.SUBSCRIBED, subscribeHandler); + return () => { + window.removeEventListener(HookEvents.SUBSCRIBED, subscribeHandler); + }; + }, []); + useEffect(() => { const dataResult = { data: dataResultFromSubscription.data, @@ -91,7 +111,7 @@ export const DataChannelItemManagerReader: React.ElementType { + const useDataChannelHandlerFunction = ((msg: object, options?: PushEntryFunctionOptionArgument) => { + const { + receivers: objectsTo, + } = options || { + receivers: undefined, + }; const argumentsOfPushEntryFunction = { variables: { pluginName, channelName, subChannelName, - payloadJson: JSON.stringify(msg), + payloadJson: msg, toRoles: [], toUserIds: [], } as MutationVariables, @@ -82,7 +93,7 @@ const DataChannelItemManagerWriter: React.ElementType 0) argumentsOfPushEntryFunction.variables.toRoles = rolesTo; if (usersTo.length > 0) argumentsOfPushEntryFunction.variables.toUserIds = usersTo; } - pushEntryFunctionPluginDataChannelMessage(argumentsOfPushEntryFunction); + pushEntryFunctionPluginDataChannel(argumentsOfPushEntryFunction); }) as PushEntryFunction; pluginApi.mapOfPushEntryFunctions[dataChannelIdentifier] = useDataChannelHandlerFunction; @@ -93,18 +104,18 @@ const DataChannelItemManagerWriter: React.ElementType; const hookArguments = eventDetails?.hookArguments as DataChannelArguments | undefined; - deleteEntryFunctionPluginDataChannelMessage({ + deleteEntryFunctionPluginDataChannel({ variables: { pluginName: hookArguments?.pluginName, channelName: hookArguments?.channelName, - messageId: eventDetails.data, + entryId: eventDetails.data, subChannelName, }, }); } else if (event.detail.hook === DataChannelHooks.DATA_CHANNEL_RESET) { const eventDetails = event.detail as UpdatedEventDetails; const hookArguments = eventDetails?.hookArguments as DataChannelArguments | undefined; - resetFunctionPluginDataChannelMessage({ + resetFunctionPluginDataChannel({ variables: { pluginName: hookArguments?.pluginName, channelName: hookArguments?.channelName, @@ -114,10 +125,29 @@ const DataChannelItemManagerWriter: React.ElementType) => { + if (event.detail.hook === DataChannelHooks.DATA_CHANNEL_REPLACE) { + const eventDetails = event.detail as UpdatedEventDetails>; + const hookArguments = eventDetails?.hookArguments as DataChannelArguments | undefined; + replaceEntryFunctionPluginDataChannel({ + variables: { + pluginName: hookArguments?.pluginName, + channelName: hookArguments?.channelName, + subChannelName: hookArguments?.subChannelName, + entryId: eventDetails.data.entryId, + payloadJson: eventDetails.data.payloadJson, + }, + }); + } + }) as EventListener; + useEffect(() => { window.addEventListener(HookEvents.UPDATED, deleteOrResetHandler); + window.addEventListener(HookEvents.UPDATED, replaceEntryHandler); return () => { window.removeEventListener(HookEvents.UPDATED, deleteOrResetHandler); + window.removeEventListener(HookEvents.UPDATED, replaceEntryHandler); }; }, []); return null; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/manager.tsx index 3182ac9ab7..156ba0f891 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/manager.tsx +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/manager.tsx @@ -48,7 +48,7 @@ const PluginDataChannelManager: React.ElementType totalUses: (previousMap.get(uniqueId)?.totalUses || 0) + deltaSubscribe, subChannelName, channelName, - types: newArrayTypes, + types: [...new Set(newArrayTypes)], }); return newMap; } diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/mutations.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/mutations.ts index b26060cd52..77401bb757 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/mutations.ts +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/mutations.ts @@ -1,8 +1,9 @@ import { gql } from '@apollo/client'; export const PLUGIN_DATA_CHANNEL_PUSH_MUTATION = gql` - mutation PluginDataChannelPushEntry($pluginName: String!, - $subChannelName: String!, $channelName: String!, $payloadJson: String!, + mutation PluginDataChannelPushEntry($pluginName: String!, + $subChannelName: String!, $channelName: String!, + $payloadJson: json!, $toRoles: [String]!, $toUserIds: [String]!) { pluginDataChannelPushEntry( pluginName: $pluginName, @@ -36,3 +37,17 @@ export const PLUGIN_DATA_CHANNEL_DELETE_MUTATION = gql` ) } `; + +export const PLUGIN_DATA_CHANNEL_REPLACE_MUTATION = gql` + mutation PluginDataChannelReplaceEntry($pluginName: String!, + $subChannelName: String!, $channelName: String!, + $payloadJson: json!, $entryId: String!) { + pluginDataChannelReplaceEntry( + entryId: $entryId, + pluginName: $pluginName, + channelName: $channelName, + subChannelName: $subChannelName, + payloadJson: $payloadJson + ) + } +`; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/subscriptions.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/subscriptions.ts index 50a6329f90..dbae7c7ef4 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/subscriptions.ts +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-channel/subscriptions.ts @@ -1,7 +1,7 @@ import { gql } from '@apollo/client'; const PLUGIN_DATA_CHANNEL_NEW_ITEMS = gql` - subscription FetchPluginDataChannelEntryMsg($pluginName: String!, + subscription FetchPluginDataChannelEntry($pluginName: String!, $channelName: String! , $createdAt: timestamptz!, $subChannelName: String!){ pluginDataChannelEntry_stream( cursor: {initial_value: {createdAt: $createdAt}}, batch_size: 100, @@ -16,7 +16,7 @@ const PLUGIN_DATA_CHANNEL_NEW_ITEMS = gql` subChannelName, entryId, payloadJson, - fromUserId, + createdBy, pluginName, toRoles, } @@ -24,7 +24,7 @@ const PLUGIN_DATA_CHANNEL_NEW_ITEMS = gql` `; const PLUGIN_DATA_CHANNEL_All_ITEMS = gql` - subscription FetchPluginDataChannelEntryMsg($pluginName: String!, + subscription FetchPluginDataChannelEntry($pluginName: String!, $channelName: String!, $subChannelName: String! ){ pluginDataChannelEntry( @@ -40,7 +40,7 @@ const PLUGIN_DATA_CHANNEL_All_ITEMS = gql` subChannelName, entryId, payloadJson, - fromUserId, + createdBy, pluginName, toRoles, } @@ -48,7 +48,7 @@ const PLUGIN_DATA_CHANNEL_All_ITEMS = gql` `; const PLUGIN_DATA_CHANNEL_LATEST_ITEM = gql` - subscription FetchPluginDataChannelEntryMsg($pluginName: String!, + subscription FetchPluginDataChannelEntry($pluginName: String!, $channelName: String!, $subChannelName: String! ){ pluginDataChannelEntry( @@ -65,7 +65,7 @@ const PLUGIN_DATA_CHANNEL_LATEST_ITEM = gql` subChannelName, entryId, payloadJson, - fromUserId, + createdBy, pluginName, toRoles, } diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/chat/loaded-chat-messages/hook-manager.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/chat/loaded-chat-messages/hook-manager.ts index 8ae23c7e9a..9b7784b4d6 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/chat/loaded-chat-messages/hook-manager.ts +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/chat/loaded-chat-messages/hook-manager.ts @@ -19,6 +19,7 @@ const LoadedChatMessagesHookContainer = () => { message: message.message, messageId: message.messageId, user: message.user, + messageMetadata: message.messageMetadata, })); const updateLoadedChatMessagesForPlugin = () => { diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/chat/loaded-chat-messages/utils.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/chat/loaded-chat-messages/utils.ts index bd806304f8..775a7e7988 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/chat/loaded-chat-messages/utils.ts +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/chat/loaded-chat-messages/utils.ts @@ -9,6 +9,7 @@ const formatLoadedChatMessagesDataFromGraphql = ( message: chatMessagesData.message, messageId: chatMessagesData.messageId, senderUserId: chatMessagesData.user?.userId, + messageMetadata: chatMessagesData.messageMetadata, }) as PluginSdk.LoadedChatMessage), loading: !(responseData), error: undefined, diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/shared/custom-subscription/hook-manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/shared/custom-subscription/hook-manager.tsx index 1e35d7bf5d..abcddf0306 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/shared/custom-subscription/hook-manager.tsx +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/data-consumption/domain/shared/custom-subscription/hook-manager.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { useSubscription, gql } from '@apollo/client'; +import { gql } from '@apollo/client'; import logger from '/imports/startup/client/logger'; import { CustomSubscriptionArguments } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-consumption/domain/shared/custom-subscription/types'; import { SubscribedEventDetails, UpdatedEventDetails } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/types'; @@ -9,6 +9,7 @@ import { import { DataConsumptionHooks } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-consumption/enums'; import { HookWithArgumentsContainerProps } from './types'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; /* eslint-disable @typescript-eslint/no-explicit-any */ const CustomSubscriptionHookContainer = (props: HookWithArgumentsContainerProps) => { @@ -19,7 +20,7 @@ const CustomSubscriptionHookContainer = (props: HookWithArgumentsContainerProps) let customSubscriptionData: any; try { - const subscriptionResult = useSubscription(gql`${queryFromPlugin}`, { + const subscriptionResult = useDeduplicatedSubscription(gql`${queryFromPlugin}`, { variables, }); customSubscriptionData = subscriptionResult; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/dom-element-manipulation/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/dom-element-manipulation/manager.tsx index 2917aef1fc..bb109c2ed0 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/dom-element-manipulation/manager.tsx +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/dom-element-manipulation/manager.tsx @@ -6,11 +6,13 @@ import { HookEventWrapper } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/ty import { DomElementManipulationHooks } from 'bigbluebutton-html-plugin-sdk/dist/cjs/dom-element-manipulation/enums'; import ChatMessageDomElementManipulationHookManager from './chat/message/hook-manager'; +import UserCameraDomElementManipulationHookManager from './user-camera/hook-manager'; const hooksMap:{ [key: string]: React.FunctionComponent } = { [DomElementManipulationHooks.CHAT_MESSAGE]: ChatMessageDomElementManipulationHookManager, + [DomElementManipulationHooks.USER_CAMERA]: UserCameraDomElementManipulationHookManager, }; const PluginDomElementManipulationManager: React.FC = () => { diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/dom-element-manipulation/user-camera/hook-manager.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/dom-element-manipulation/user-camera/hook-manager.ts new file mode 100644 index 0000000000..f7bc3fdc8a --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/dom-element-manipulation/user-camera/hook-manager.ts @@ -0,0 +1,43 @@ +import { useContext, useEffect } from 'react'; +import { HookEventWrapper, SubscribedEventDetails } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/types'; +import { HookEvents } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/enum'; +import { DomElementManipulationHooks } from 'bigbluebutton-html-plugin-sdk/dist/cjs/dom-element-manipulation/enums'; +import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; +import { UserCameraDomElementsArguments } from 'bigbluebutton-html-plugin-sdk/dist/cjs/dom-element-manipulation/user-camera/types'; + +const UserCameraDomElementManipulationHookManager = () => { + const { + setDomElementManipulationStreamIds, + } = useContext(PluginsContext); + + useEffect(() => { + const subscribeHandler: EventListener = ( + (event: HookEventWrapper) => { + let hookArguments: UserCameraDomElementsArguments | undefined; + if (event.detail.hook === DomElementManipulationHooks.USER_CAMERA) { + const detail = event.detail as SubscribedEventDetails; + hookArguments = detail.hookArguments as UserCameraDomElementsArguments; + setDomElementManipulationStreamIds(hookArguments.streamIds); + } + }) as EventListener; + const unsubscribeHandler: EventListener = ( + (event: HookEventWrapper) => { + let hookArguments: UserCameraDomElementsArguments | undefined; + if (event.detail.hook === DomElementManipulationHooks.USER_CAMERA) { + const detail = event.detail as SubscribedEventDetails; + hookArguments = detail.hookArguments as UserCameraDomElementsArguments; + setDomElementManipulationStreamIds(hookArguments.streamIds); + } + }) as EventListener; + + window.addEventListener(HookEvents.SUBSCRIBED, subscribeHandler); + window.addEventListener(HookEvents.UNSUBSCRIBED, unsubscribeHandler); + return () => { + window.removeEventListener(HookEvents.SUBSCRIBED, subscribeHandler); + window.removeEventListener(HookEvents.UNSUBSCRIBED, unsubscribeHandler); + }; + }, []); + return null; +}; + +export default UserCameraDomElementManipulationHookManager; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/components/generic-component/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/components/generic-content/manager.tsx similarity index 64% rename from bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/components/generic-component/manager.tsx rename to bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/components/generic-content/manager.tsx index 3dbc6e5a3f..f8e8ef8fd2 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/components/generic-component/manager.tsx +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/components/generic-content/manager.tsx @@ -7,7 +7,7 @@ import { } from '../../types'; import { PluginsContext } from '../../../../components-data/plugin-context/context'; -const GenericComponentPluginStateContainer = (( +const GenericContentPluginStateContainer = (( props: ExtensibleAreaComponentManagerProps, ) => { const { @@ -17,9 +17,9 @@ const GenericComponentPluginStateContainer = (( pluginApi, } = props; const [ - genericComponents, - setGenericComponents, - ] = useState([]); + genericContentItems, + setGenericContentItems, + ] = useState([]); const { pluginsExtensibleAreasAggregatedState, @@ -28,28 +28,28 @@ const GenericComponentPluginStateContainer = (( useEffect(() => { // Change this plugin provided toolbar items - extensibleAreaMap[uuid].genericComponents = genericComponents; + extensibleAreaMap[uuid].genericContentItems = genericContentItems; // Update context with computed aggregated list of all plugin provided toolbar items - const aggregatedGenericComponents = ( - [] as PluginSdk.GenericComponentInterface[]).concat( + const aggregatedGenericContentItems = ( + [] as PluginSdk.GenericContentInterface[]).concat( ...Object.values(extensibleAreaMap) - .map((extensibleArea: ExtensibleArea) => extensibleArea.genericComponents), + .map((extensibleArea: ExtensibleArea) => extensibleArea.genericContentItems), ); setPluginsExtensibleAreasAggregatedState( { ...pluginsExtensibleAreasAggregatedState, - genericComponents: aggregatedGenericComponents, + genericContentItems: aggregatedGenericContentItems, }, ); - }, [genericComponents]); + }, [genericContentItems]); - pluginApi.setGenericComponents = (items: PluginSdk.GenericComponentInterface[]) => { - const itemsWithId = items.map(generateItemWithId) as PluginSdk.GenericComponentInterface[]; - setGenericComponents(itemsWithId); + pluginApi.setGenericContentItems = (items: PluginSdk.GenericContentInterface[]) => { + const itemsWithId = items.map(generateItemWithId) as PluginSdk.GenericContentInterface[]; + setGenericContentItems(itemsWithId); return itemsWithId.map((i) => i.id); }; return null; }) as ExtensibleAreaComponentManager; -export default GenericComponentPluginStateContainer; +export default GenericContentPluginStateContainer; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/components/screenshare-helper/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/components/screenshare-helper/manager.tsx new file mode 100644 index 0000000000..c67919c7b3 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/components/screenshare-helper/manager.tsx @@ -0,0 +1,53 @@ +import { useEffect, useState, useContext } from 'react'; +import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; + +import { + ExtensibleAreaComponentManagerProps, ExtensibleArea, + ExtensibleAreaComponentManager, +} from '../../types'; +import { PluginsContext } from '../../../../components-data/plugin-context/context'; + +const ScreenshareHelperPluginStateContainer = (( + props: ExtensibleAreaComponentManagerProps, +) => { + const { + uuid, + generateItemWithId, + extensibleAreaMap, + pluginApi, + } = props; + const [ + screenshareHelperItems, + setScreenshareHelperItems, + ] = useState([]); + + const { + pluginsExtensibleAreasAggregatedState, + setPluginsExtensibleAreasAggregatedState, + } = useContext(PluginsContext); + + useEffect(() => { + extensibleAreaMap[uuid].screenshareHelperItems = screenshareHelperItems; + + const aggregatedScreenshareHelperItems = ([] as PluginSdk.ScreenshareHelperInterface[]).concat( + ...Object.values(extensibleAreaMap) + .map((extensibleArea: ExtensibleArea) => extensibleArea.screenshareHelperItems), + ); + + setPluginsExtensibleAreasAggregatedState( + { + ...pluginsExtensibleAreasAggregatedState, + screenshareHelperItems: aggregatedScreenshareHelperItems, + }, + ); + }, [screenshareHelperItems]); + + pluginApi.setScreenshareHelperItems = (items: PluginSdk.ScreenshareHelperInterface[]) => { + const itemsWithId = items.map(generateItemWithId) as PluginSdk.ScreenshareHelperInterface[]; + setScreenshareHelperItems(itemsWithId); + return itemsWithId.map((i) => i.id); + }; + return null; +}) as ExtensibleAreaComponentManager; + +export default ScreenshareHelperPluginStateContainer; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/manager.tsx index 3b53af7d80..ae2cba6171 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/manager.tsx +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/manager.tsx @@ -18,7 +18,8 @@ import { ExtensibleAreaComponentManager, ExtensibleAreaMap, } from './types'; import FloatingWindowPluginStateContainer from './components/floating-window/manager'; -import GenericComponentPluginStateContainer from './components/generic-component/manager'; +import GenericContentPluginStateContainer from './components/generic-content/manager'; +import ScreenshareHelperPluginStateContainer from './components/screenshare-helper/manager'; const extensibleAreaMap: ExtensibleAreaMap = {}; @@ -35,7 +36,8 @@ const extensibleAreaComponentManagers: ExtensibleAreaComponentManager[] = [ UserCameraDropdownPluginStateContainer, UserListItemAdditionalInformationPluginStateContainer, FloatingWindowPluginStateContainer, - GenericComponentPluginStateContainer, + GenericContentPluginStateContainer, + ScreenshareHelperPluginStateContainer, ]; function generateItemWithId( diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/types.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/types.ts index dc7389d73e..3e0bd383f7 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/types.ts +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/extensible-areas/types.ts @@ -15,12 +15,13 @@ export interface ExtensibleArea { actionsBarItems: PluginSdk.ActionsBarInterface[]; presentationDropdownItems: PluginSdk.PresentationDropdownInterface[]; navBarItems: PluginSdk.NavBarInterface[]; + screenshareHelperItems: PluginSdk.ScreenshareHelperInterface[]; optionsDropdownItems: PluginSdk.OptionsDropdownInterface[]; cameraSettingsDropdownItems: PluginSdk.CameraSettingsDropdownInterface[]; userCameraDropdownItems: PluginSdk.UserCameraDropdownInterface[]; userListItemAdditionalInformation: PluginSdk.UserListItemAdditionalInformationInterface[]; floatingWindows: PluginSdk.FloatingWindowInterface[] - genericComponents: PluginSdk.GenericComponentInterface[] + genericContentItems: PluginSdk.GenericContentInterface[] } /** diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/learning-analytics-dashboard/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/learning-analytics-dashboard/manager.tsx new file mode 100644 index 0000000000..7c76d67507 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/learning-analytics-dashboard/manager.tsx @@ -0,0 +1,43 @@ +import { useEffect } from 'react'; +import { LearningAnalyticsDashboardEventDetails } from 'bigbluebutton-html-plugin-sdk/dist/cjs/learning-analytics-dashboard/types'; +import { LearningAnalyticsDashboardEvents } from 'bigbluebutton-html-plugin-sdk/dist/cjs/learning-analytics-dashboard/enums'; +import { useMutation } from '@apollo/client'; +import PLUGIN_LEARNING_ANALYTICS_DASHBOARD_SEND_GENERIC_DATA_MUTATION from './mutations'; +import { PluginLearningAnalyticsDashboardManagerProps } from './types'; + +const PluginLearningAnalyticsDashboardManager: React.ElementType< + PluginLearningAnalyticsDashboardManagerProps> = (( + props: PluginLearningAnalyticsDashboardManagerProps, + ) => { + const { pluginName } = props; + + const [sendGenericDataToLearningAnalyticsDashboard] = useMutation( + PLUGIN_LEARNING_ANALYTICS_DASHBOARD_SEND_GENERIC_DATA_MUTATION, + ); + + const handleSendGenericDataForLearningAnalyticsDashboard: EventListener = ( + (event: CustomEvent) => { + if (event.detail.pluginName === pluginName) { + const eventDetails = event.detail as LearningAnalyticsDashboardEventDetails; + sendGenericDataToLearningAnalyticsDashboard({ + variables: { + pluginName: eventDetails.pluginName, + genericDataForLearningAnalyticsDashboard: eventDetails.data, + }, + }); + } + }) as EventListener; + + useEffect(() => { + window.addEventListener( + LearningAnalyticsDashboardEvents.GENERIC_DATA_SENT, handleSendGenericDataForLearningAnalyticsDashboard, + ); + return () => { + window.removeEventListener( + LearningAnalyticsDashboardEvents.GENERIC_DATA_SENT, handleSendGenericDataForLearningAnalyticsDashboard, + ); + }; + }, []); + }) as React.ElementType; + +export default PluginLearningAnalyticsDashboardManager; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/learning-analytics-dashboard/mutations.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/learning-analytics-dashboard/mutations.ts new file mode 100644 index 0000000000..eadae7eb45 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/learning-analytics-dashboard/mutations.ts @@ -0,0 +1,13 @@ +import { gql } from '@apollo/client'; + +const PLUGIN_LEARNING_ANALYTICS_DASHBOARD_SEND_GENERIC_DATA_MUTATION = gql` + mutation PluginLearningAnalyticsDashboardSendGenericData($pluginName: String!, + $genericDataForLearningAnalyticsDashboard: json!) { + pluginLearningAnalyticsDashboardSendGenericData( + genericDataForLearningAnalyticsDashboard: $genericDataForLearningAnalyticsDashboard, + pluginName: $pluginName, + ) + } +`; + +export default PLUGIN_LEARNING_ANALYTICS_DASHBOARD_SEND_GENERIC_DATA_MUTATION; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/learning-analytics-dashboard/types.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/learning-analytics-dashboard/types.ts new file mode 100644 index 0000000000..1b95cee7ce --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/learning-analytics-dashboard/types.ts @@ -0,0 +1,3 @@ +export interface PluginLearningAnalyticsDashboardManagerProps { + pluginName: string; +} diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/loader/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/loader/manager.tsx index df63666fa3..b3bd320bfb 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/loader/manager.tsx +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/loader/manager.tsx @@ -20,18 +20,29 @@ const PluginLoaderManager = (props: PluginLoaderManagerProps) => { div.id = uuid; containerRef.current?.appendChild(div); - const script = document.createElement('script'); + const script: HTMLScriptElement = document.createElement('script'); script.onload = () => { loadedPlugins.current += 1; setLastLoadedPlugin(script); - logger.info(`Loaded plugin ${plugin.name}`); + logger.info({ + logCode: 'plugin_loaded', + }, `Loaded plugin ${plugin.name}`); }; - script.onerror = (err) => { - logger.error(`Error when loading plugin ${plugin.name}, error: `, err); + script.onerror = () => { + logger.error({ + logCode: 'plugin_load_error', + extraInfo: { + pluginName: plugin.name, + pluginUrl: plugin.url, + }, + }, `Error when loading plugin ${plugin.name}`); }; script.src = plugin.url; script.setAttribute('uuid', div.id); script.setAttribute('pluginName', plugin.name); + if (plugin.checksum) { + script.setAttribute('integrity', plugin.checksum); + } document.head.appendChild(script); }, [plugin, containerRef]); return null; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/manager.tsx index d524175690..de09ba0837 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/manager.tsx +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/manager.tsx @@ -15,12 +15,14 @@ import ExtensibleAreaStateManager from './extensible-areas/manager'; import PluginDataChannelManager from './data-channel/manager'; import PluginUiCommandsHandler from './ui-commands/handler'; import PluginDomElementManipulationManager from './dom-element-manipulation/manager'; - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore - temporary, while meteor exists in the project -const PLUGINS_CONFIG = window.meetingClientSettings.public.plugins; +import PluginServerCommandsHandler from './server-commands/handler'; +import PluginLearningAnalyticsDashboardManager from './learning-analytics-dashboard/manager'; const PluginsEngineManager = () => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore - temporary, while meteor exists in the project + const PLUGINS_CONFIG = window.meetingClientSettings.public.plugins; + // If there is no plugin to load, the engine simply returns null if (!PLUGINS_CONFIG) return null; @@ -53,6 +55,7 @@ const PluginsEngineManager = () => { }} /> + { @@ -70,6 +73,9 @@ const PluginsEngineManager = () => { pluginConfig: effectivePluginConfig, }} /> + { + const [captionAddLocale] = useMutation(CAPTION_ADD_LOCALE); + const handleCaptionAddLocale = (( + event: CustomEvent, + ) => { + captionAddLocale({ + variables: { + locale: event.detail, + }, + }); + }) as EventListener; + + useEffect(() => { + window.addEventListener(CaptionCommandsEnum.ADD_LOCALE, handleCaptionAddLocale); + + return () => { + window.removeEventListener(CaptionCommandsEnum.ADD_LOCALE, handleCaptionAddLocale); + }; + }, []); + return null; +}; + +export default PluginAddLocaleCaptionServerCommandsManager; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/caption/add-locale/mutations.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/caption/add-locale/mutations.ts new file mode 100644 index 0000000000..4bb07f03f5 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/caption/add-locale/mutations.ts @@ -0,0 +1,11 @@ +import { gql } from '@apollo/client'; + +export const CAPTION_ADD_LOCALE = gql` + mutation CaptionAddLocale($locale: String!) { + captionAddLocale( + locale: $locale + ) + } +`; + +export default CAPTION_ADD_LOCALE; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/caption/save/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/caption/save/manager.tsx new file mode 100644 index 0000000000..cda0b9c787 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/caption/save/manager.tsx @@ -0,0 +1,35 @@ +import { useEffect } from 'react'; +import { CaptionSaveCommandArguments } from 'bigbluebutton-html-plugin-sdk/dist/cjs/server-commands/caption/types'; +import { useMutation } from '@apollo/client'; +import * as uuidLib from 'uuid'; +import { + CaptionCommandsEnum, +} from 'bigbluebutton-html-plugin-sdk/dist/cjs/server-commands/caption/enum'; +import SUBMIT_TRANSCRIPT from './mutations'; + +const PluginSaveCaptionServerCommandsManager = () => { + const [submitTranscript] = useMutation(SUBMIT_TRANSCRIPT); + const handleSubmitCaption = (( + event: CustomEvent, + ) => { + submitTranscript({ + variables: { + transcriptId: uuidLib.v4(), + transcript: event.detail.text, + locale: event.detail.locale, + captionType: event.detail.captionType, + }, + }); + }) as EventListener; + + useEffect(() => { + window.addEventListener(CaptionCommandsEnum.SAVE, handleSubmitCaption); + + return () => { + window.removeEventListener(CaptionCommandsEnum.SAVE, handleSubmitCaption); + }; + }, []); + return null; +}; + +export default PluginSaveCaptionServerCommandsManager; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/caption/save/mutations.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/caption/save/mutations.ts new file mode 100644 index 0000000000..55a3c10d41 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/caption/save/mutations.ts @@ -0,0 +1,19 @@ +import { gql } from '@apollo/client'; + +const SUBMIT_TRANSCRIPT = gql` + mutation ( + $transcriptId: String! + $transcript: String! + $locale: String! + $captionType: String! + ) { + captionSubmitTranscript( + transcriptId: $transcriptId, + transcript: $transcript, + locale: $locale, + captionType: $captionType + ) + } +`; + +export default SUBMIT_TRANSCRIPT; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/chat/send-message/manager.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/chat/send-message/manager.tsx new file mode 100644 index 0000000000..17eb16ce2c --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/chat/send-message/manager.tsx @@ -0,0 +1,37 @@ +import { useEffect } from 'react'; +import { ChatSendMessageEventArguments } from 'bigbluebutton-html-plugin-sdk/dist/cjs/server-commands/chat/types'; +import { useMutation } from '@apollo/client'; +import { + ChatCommandsEnum, +} from 'bigbluebutton-html-plugin-sdk/dist/cjs/server-commands/chat/enum'; +import { CHAT_SEND_MESSAGE } from './mutations'; + +const PluginSendMessageChatServerCommandsManager = () => { + const [sendMessage] = useMutation(CHAT_SEND_MESSAGE); + const handleSendMessage = (( + event: CustomEvent, + ) => { + sendMessage({ + variables: { + chatId: event.detail.chatId, + chatMessageInMarkdownFormat: event.detail.textMessageInMarkdownFormat, + metadata: { + custom: event.detail.custom, + pluginName: event.detail.pluginName, + pluginCustomMetadata: event.detail?.pluginCustomMetadata, + }, + }, + }); + }) as EventListener; + + useEffect(() => { + window.addEventListener(ChatCommandsEnum.SEND_MESSAGE, handleSendMessage); + + return () => { + window.removeEventListener(ChatCommandsEnum.SEND_MESSAGE, handleSendMessage); + }; + }, []); + return null; +}; + +export default PluginSendMessageChatServerCommandsManager; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/chat/send-message/mutations.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/chat/send-message/mutations.ts new file mode 100644 index 0000000000..f8d8551a31 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/chat/send-message/mutations.ts @@ -0,0 +1,17 @@ +import { gql } from '@apollo/client'; + +export const CHAT_SEND_MESSAGE = gql` + mutation ChatSendMessage( + $chatId: String!, + $chatMessageInMarkdownFormat: String!, + $metadata: json, + ) { + chatSendMessage( + chatId: $chatId, + chatMessageInMarkdownFormat: $chatMessageInMarkdownFormat + metadata: $metadata, + ) + } +`; + +export default CHAT_SEND_MESSAGE; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/handler.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/handler.tsx new file mode 100644 index 0000000000..c00ba6267d --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/server-commands/handler.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import PluginSaveCaptionServerCommandsManager from './caption/save/manager'; +import PluginAddLocaleCaptionServerCommandsManager from './caption/add-locale/manager'; +import PluginSendMessageChatServerCommandsManager from './chat/send-message/manager'; + +const PluginServerCommandsHandler = () => ( + <> + + + + +); + +export default PluginServerCommandsHandler; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/types.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/types.ts index d72572c568..42fae08f88 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/types.ts +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/types.ts @@ -7,6 +7,7 @@ export interface PluginsEngineComponentProps { export interface PluginConfig { name: string; url: string; + checksum?: string; } export interface EffectivePluginConfig extends PluginConfig { diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/handler.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/handler.tsx index 95a4a4a898..af0866e4dc 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/handler.tsx +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/handler.tsx @@ -1,9 +1,13 @@ import * as React from 'react'; import PluginChatUiCommandsHandler from './chat/handler'; +import PluginSidekickOptionsContainerUiCommandsHandler from './sidekick-options-container/handler'; +import PluginPresentationAreaUiCommandsHandler from './presentation/handler'; const PluginUiCommandsHandler = () => ( <> + + ); diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/presentation/handler.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/presentation/handler.tsx new file mode 100644 index 0000000000..5b4a6bae17 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/presentation/handler.tsx @@ -0,0 +1,37 @@ +import { useEffect } from 'react'; +import { + PresentationAreaEnum, +} from 'bigbluebutton-html-plugin-sdk/dist/cjs/ui-commands/presentation-area/enums'; +import { layoutDispatch } from '../../../layout/context'; +import { ACTIONS } from '../../../layout/enums'; + +const PluginPresentationAreaUiCommandsHandler = () => { + const layoutContextDispatch = layoutDispatch(); + + const handlePresentationAreaOpen = () => { + layoutContextDispatch({ + type: ACTIONS.SET_PRESENTATION_IS_OPEN, + value: true, + }); + }; + + const handlePresentationAreaClose = () => { + layoutContextDispatch({ + type: ACTIONS.SET_PRESENTATION_IS_OPEN, + value: false, + }); + }; + + useEffect(() => { + window.addEventListener(PresentationAreaEnum.OPEN, handlePresentationAreaOpen); + window.addEventListener(PresentationAreaEnum.CLOSE, handlePresentationAreaClose); + + return () => { + window.addEventListener(PresentationAreaEnum.OPEN, handlePresentationAreaOpen); + window.addEventListener(PresentationAreaEnum.OPEN, handlePresentationAreaClose); + }; + }, []); + return null; +}; + +export default PluginPresentationAreaUiCommandsHandler; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/sidekick-options-container/handler.tsx b/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/sidekick-options-container/handler.tsx new file mode 100644 index 0000000000..2ad7dd5dca --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-commands/sidekick-options-container/handler.tsx @@ -0,0 +1,45 @@ +import { useEffect } from 'react'; +import { + SidekickOptionsContainerEnum, +} from 'bigbluebutton-html-plugin-sdk/dist/cjs/ui-commands/sidekick-options-container/enums'; +import { layoutDispatch } from '../../../layout/context'; +import { PANELS, ACTIONS } from '../../../layout/enums'; + +const PluginSidekickOptionsContainerUiCommandsHandler = () => { + const layoutContextDispatch = layoutDispatch(); + + const handleSidekickOptionsContainerOpen = () => { + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_NAVIGATION_IS_OPEN, + value: true, + }); + }; + + const handleSidekickOptionsContainerClose = () => { + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_NAVIGATION_IS_OPEN, + value: false, + }); + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, + value: PANELS.NONE, + }); + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, + value: false, + }); + }; + + useEffect(() => { + window.addEventListener(SidekickOptionsContainerEnum.OPEN, handleSidekickOptionsContainerOpen); + window.addEventListener(SidekickOptionsContainerEnum.CLOSE, handleSidekickOptionsContainerClose); + + return () => { + window.addEventListener(SidekickOptionsContainerEnum.OPEN, handleSidekickOptionsContainerOpen); + window.addEventListener(SidekickOptionsContainerEnum.OPEN, handleSidekickOptionsContainerClose); + }; + }, []); + return null; +}; + +export default PluginSidekickOptionsContainerUiCommandsHandler; diff --git a/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-data-hooks/layout/presentation-area/utils.ts b/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-data-hooks/layout/presentation-area/utils.ts index 3409aebf9d..5223d1d35c 100644 --- a/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-data-hooks/layout/presentation-area/utils.ts +++ b/bigbluebutton-html5/imports/ui/components/plugins-engine/ui-data-hooks/layout/presentation-area/utils.ts @@ -13,7 +13,7 @@ const useUpdatePresentationAreaContentForPluginForPlugin = (layoutContextState: useEffect(() => { setPresentationAreaContent(presentationAreaContentPile.map((p) => { let currentElement; - let genericComponentId; + let genericContentId; switch (p.value.content) { case PRESENTATION_AREA.PINNED_NOTES: currentElement = UiLayouts.PINNED_SHARED_NOTES; @@ -21,9 +21,9 @@ const useUpdatePresentationAreaContentForPluginForPlugin = (layoutContextState: case PRESENTATION_AREA.EXTERNAL_VIDEO: currentElement = UiLayouts.EXTERNAL_VIDEO; break; - case PRESENTATION_AREA.GENERIC_COMPONENT: - currentElement = UiLayouts.GENERIC_COMPONENT; - genericComponentId = p.value.genericComponentId; + case PRESENTATION_AREA.GENERIC_CONTENT: + currentElement = UiLayouts.GENERIC_CONTENT; + genericContentId = p.value.genericContentId; break; case PRESENTATION_AREA.SCREEN_SHARE: currentElement = UiLayouts.SCREEN_SHARE; @@ -35,7 +35,7 @@ const useUpdatePresentationAreaContentForPluginForPlugin = (layoutContextState: return { isOpen: p.value.open, currentElement, - genericComponentId, + genericContentId, }; })); }, [layoutContextState]); diff --git a/bigbluebutton-html5/imports/ui/components/poll/component.tsx b/bigbluebutton-html5/imports/ui/components/poll/component.tsx index 828ccf4e75..cc31897901 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/poll/component.tsx @@ -1,10 +1,8 @@ import React, { useEffect, useRef, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { Session } from 'meteor/session'; -import { Meteor } from 'meteor/meteor'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; import Header from '/imports/ui/components/common/control-header/component'; -import { useMutation, useSubscription } from '@apollo/client'; +import { useMutation } from '@apollo/client'; import { Input } from '../layout/layoutTypes'; import { layoutDispatch, layoutSelectInput } from '../layout/context'; import { addAlert } from '../screenreader-alert/service'; @@ -20,10 +18,8 @@ import ResponseChoices from './components/ResponseChoices'; import ResponseTypes from './components/ResponseTypes'; import PollQuestionArea from './components/PollQuestionArea'; import LiveResultContainer from './components/LiveResult'; - -const POLL_SETTINGS = Meteor.settings.public.poll; -const ALLOW_CUSTOM_INPUT = POLL_SETTINGS.allowCustomResponseInput; -const MAX_CUSTOM_FIELDS = POLL_SETTINGS.maxCustom; +import Session from '/imports/ui/services/storage/in-memory'; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; const intlMessages = defineMessages({ pollPaneTitle: { @@ -242,6 +238,9 @@ const PollCreationPanel: React.FC = ({ hasPoll, hasCurrentPresentation, }) => { + const POLL_SETTINGS = window.meetingClientSettings.public.poll; + const ALLOW_CUSTOM_INPUT = POLL_SETTINGS.allowCustomResponseInput; + const MAX_CUSTOM_FIELDS = POLL_SETTINGS.maxCustom; const [stopPoll] = useMutation(POLL_CANCEL); const intl = useIntl(); @@ -349,7 +348,7 @@ const PollCreationPanel: React.FC = ({ const handleToggle = () => { const toggledValue = !secretPoll; - Session.set('secretPoll', toggledValue); + Session.setItem('secretPoll', toggledValue); setSecretPoll(toggledValue); }; @@ -372,7 +371,7 @@ const PollCreationPanel: React.FC = ({ useEffect(() => { return () => { - Session.set('secretPoll', false); + Session.setItem('secretPoll', false); }; }, []); @@ -504,8 +503,8 @@ const PollCreationPanel: React.FC = ({ type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, value: PANELS.NONE, }); - Session.set('forcePollOpen', false); - Session.set('pollInitiated', false); + Session.setItem('forcePollOpen', false); + Session.setItem('pollInitiated', false); }, }} customRightButton={null} @@ -543,7 +542,7 @@ const PollCreationPanelContainer: React.FC = () => { const { data: getHasCurrentPresentationData, loading: getHasCurrentPresentationLoading, - } = useSubscription(getHasCurrentPresentation); + } = useDeduplicatedSubscription(getHasCurrentPresentation); if (currentUserLoading || !currentUser) return null; if (currentMeetingLoading || !currentMeeting) return null; diff --git a/bigbluebutton-html5/imports/ui/components/poll/components/EmptySlideArea.tsx b/bigbluebutton-html5/imports/ui/components/poll/components/EmptySlideArea.tsx index 358da3373f..46f42f496f 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/components/EmptySlideArea.tsx +++ b/bigbluebutton-html5/imports/ui/components/poll/components/EmptySlideArea.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { Session } from 'meteor/session'; +import Session from '/imports/ui/services/storage/in-memory'; import Styled from '../styles'; const intlMessages = defineMessages({ @@ -24,7 +24,7 @@ const EmptySlideArea: React.FC = () => { Session.set('showUploadPresentationView', true)} + onClick={() => Session.setItem('showUploadPresentationView', true)} /> ); diff --git a/bigbluebutton-html5/imports/ui/components/poll/components/LiveResult.tsx b/bigbluebutton-html5/imports/ui/components/poll/components/LiveResult.tsx index 55ac68eae2..7e0684779d 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/components/LiveResult.tsx +++ b/bigbluebutton-html5/imports/ui/components/poll/components/LiveResult.tsx @@ -1,7 +1,7 @@ -import { useMutation, useSubscription } from '@apollo/client'; +import { useMutation } from '@apollo/client'; import React, { useCallback } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { Session } from 'meteor/session'; +import Session from '/imports/ui/services/storage/in-memory'; import { Bar, BarChart, ResponsiveContainer, XAxis, YAxis, } from 'recharts'; @@ -13,10 +13,11 @@ import { getCurrentPollDataResponse, } from '../queries'; import logger from '/imports/startup/client/logger'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import { POLL_CANCEL, POLL_PUBLISH_RESULT } from '../mutations'; import { layoutDispatch } from '../../layout/context'; import { ACTIONS, PANELS } from '../../layout/enums'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const intlMessages = defineMessages({ usersTitle: { @@ -68,9 +69,6 @@ interface LiveResultProps { isSecret: boolean; } -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_group_id; - const LiveResult: React.FC = ({ questionText, responses, @@ -81,6 +79,9 @@ const LiveResult: React.FC = ({ users, isSecret, }) => { + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_group_id; + const intl = useIntl(); const [pollPublishResult] = useMutation(POLL_PUBLISH_RESULT); const [stopPoll] = useMutation(POLL_CANCEL); @@ -131,7 +132,7 @@ const LiveResult: React.FC = ({ { - Session.set('pollInitiated', false); + Session.setItem('pollInitiated', false); publishPoll(pollId); stopPoll(); layoutContextDispatch({ @@ -154,8 +155,8 @@ const LiveResult: React.FC = ({ /> { - Session.set('pollInitiated', false); - Session.set('resetPollPanel', true); + Session.setItem('pollInitiated', false); + Session.setItem('resetPollPanel', true); stopPoll(); }} label={intl.formatMessage(intlMessages.cancelPollLabel)} @@ -208,7 +209,7 @@ const LiveResultContainer: React.FC = () => { data: currentPollData, loading: currentPollLoading, error: currentPollDataError, - } = useSubscription(getCurrentPollData); + } = useDeduplicatedSubscription(getCurrentPollData); if (currentPollLoading || !currentPollData) { return null; @@ -224,6 +225,7 @@ const LiveResultContainer: React.FC = () => { } if (!currentPollData.poll.length) return null; + const Settings = getSettingsSingletonInstance(); // @ts-ignore - JS code const { animations } = Settings.application; const currentPoll = currentPollData.poll[0]; diff --git a/bigbluebutton-html5/imports/ui/components/poll/components/PollInputs.tsx b/bigbluebutton-html5/imports/ui/components/poll/components/PollInputs.tsx index 04283ac632..0438e86b2d 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/components/PollInputs.tsx +++ b/bigbluebutton-html5/imports/ui/components/poll/components/PollInputs.tsx @@ -1,14 +1,8 @@ import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { Meteor } from 'meteor/meteor'; import { pollTypes } from '../service'; import Styled from '../styles'; -const POLL_SETTINGS = Meteor.settings.public.poll; -const MAX_CUSTOM_FIELDS = POLL_SETTINGS.maxCustom; -const MAX_INPUT_CHARS = POLL_SETTINGS.maxTypedAnswerLength; -const MIN_OPTIONS_LENGTH = 2; - const intlMessages = defineMessages({ customPlaceholder: { id: 'app.poll.customPlaceholder', @@ -43,6 +37,10 @@ const PollInputs: React.FC = ({ type, error, }) => { + const POLL_SETTINGS = window.meetingClientSettings.public.poll; + const MAX_CUSTOM_FIELDS = POLL_SETTINGS.maxCustom; + const MAX_INPUT_CHARS = POLL_SETTINGS.maxTypedAnswerLength; + const MIN_OPTIONS_LENGTH = 2; const intl = useIntl(); let hasVal = false; return optList.slice(0, MAX_CUSTOM_FIELDS).map((o: { val: string }, i: number) => { diff --git a/bigbluebutton-html5/imports/ui/components/poll/components/PollQuestionArea.tsx b/bigbluebutton-html5/imports/ui/components/poll/components/PollQuestionArea.tsx index 6eeda5dae5..a73ab1f263 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/components/PollQuestionArea.tsx +++ b/bigbluebutton-html5/imports/ui/components/poll/components/PollQuestionArea.tsx @@ -1,13 +1,9 @@ import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { Meteor } from 'meteor/meteor'; import DraggableTextArea from './DragAndDrop'; import { pollTypes } from '../service'; import Styled from '../styles'; -const POLL_SETTINGS = Meteor.settings.public.poll; -const MAX_INPUT_CHARS = POLL_SETTINGS.maxTypedAnswerLength; - const QUESTION_MAX_INPUT_CHARS = 1200; const intlMessages = defineMessages({ @@ -52,6 +48,8 @@ const PollQuestionArea: React.FC = ({ textareaRef, question, }) => { + const POLL_SETTINGS = window.meetingClientSettings.public.poll; + const MAX_INPUT_CHARS = POLL_SETTINGS.maxTypedAnswerLength; const intl = useIntl(); const hasOptionError = (customInput && optList.length === 0 && error); const hasWarning = (customInput && warning); diff --git a/bigbluebutton-html5/imports/ui/components/poll/components/ResponseArea.tsx b/bigbluebutton-html5/imports/ui/components/poll/components/ResponseArea.tsx index 4be4ef9cd7..8be7afe2f4 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/components/ResponseArea.tsx +++ b/bigbluebutton-html5/imports/ui/components/poll/components/ResponseArea.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { Meteor } from 'meteor/meteor'; import Checkbox from '/imports/ui/components/common/checkbox/component'; import Toggle from '/imports/ui/components/common/switch/component'; import Styled from '../styles'; @@ -8,9 +7,6 @@ import { pollTypes, isDefaultPoll } from '../service'; import StartPollButton from './StartPollButton'; import PollInputs from './PollInputs'; -const POLL_SETTINGS = Meteor.settings.public.poll; -const MAX_CUSTOM_FIELDS = POLL_SETTINGS.maxCustom; - const intlMessages = defineMessages({ enableMultipleResponseLabel: { id: 'app.poll.enableMultipleResponseLabel', @@ -71,6 +67,8 @@ const ResponseArea: React.FC = ({ handleInputChange, handleRemoveOption, }) => { + const POLL_SETTINGS = window.meetingClientSettings.public.poll; + const MAX_CUSTOM_FIELDS = POLL_SETTINGS.maxCustom; const intl = useIntl(); const defaultPoll = isDefaultPoll(type as string); if (defaultPoll || type === pollTypes.Response) { diff --git a/bigbluebutton-html5/imports/ui/components/poll/components/StartPollButton.tsx b/bigbluebutton-html5/imports/ui/components/poll/components/StartPollButton.tsx index 8e4eb28f58..400bf8e57e 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/components/StartPollButton.tsx +++ b/bigbluebutton-html5/imports/ui/components/poll/components/StartPollButton.tsx @@ -1,17 +1,10 @@ import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { Meteor } from 'meteor/meteor'; import { useMutation } from '@apollo/client'; import Styled from '../styles'; import { pollTypes, checkPollType } from '../service'; import { POLL_CREATE } from '../mutations'; -const CHAT_CONFIG = Meteor.settings.public.chat; -const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_id; - -const POLL_SETTINGS = Meteor.settings.public.poll; -const MAX_CUSTOM_FIELDS = POLL_SETTINGS.maxCustom; - const intlMessages = defineMessages({ startPollLabel: { id: 'app.poll.start.label', @@ -68,6 +61,11 @@ const StartPollButton: React.FC = ({ isMultipleResponse, hasCurrentPresentation, }) => { + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_id; + + const POLL_SETTINGS = window.meetingClientSettings.public.poll; + const MAX_CUSTOM_FIELDS = POLL_SETTINGS.maxCustom; const intl = useIntl(); const [createPoll] = useMutation(POLL_CREATE); diff --git a/bigbluebutton-html5/imports/ui/components/polling/component.tsx b/bigbluebutton-html5/imports/ui/components/polling/component.tsx index 48e8cf5378..b034d525d3 100644 --- a/bigbluebutton-html5/imports/ui/components/polling/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/polling/component.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useMemo, useRef, useState, } from 'react'; -import { useMutation, useSubscription } from '@apollo/client'; +import { useMutation } from '@apollo/client'; import { defineMessages, useIntl } from 'react-intl'; import Checkbox from '/imports/ui/components/common/checkbox/component'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; @@ -15,8 +15,8 @@ import { } from './queries'; import Service from './service'; import Styled from './styles'; - -const MAX_INPUT_CHARS = window.meetingClientSettings.public.poll.maxTypedAnswerLength; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; +import { useIsPollingEnabled } from '../../services/features'; const intlMessages = defineMessages({ pollingTitleLabel: { @@ -136,6 +136,8 @@ const PollingGraphql: React.FC = (props) => { } = poll; const defaultPoll = isDefaultPoll(type); + const MAX_INPUT_CHARS = window.meetingClientSettings.public.poll.maxTypedAnswerLength; + return (
{poll.type !== pollTypes.Response && ( @@ -255,6 +257,7 @@ const PollingGraphql: React.FC = (props) => { return ( + {/* eslint-disable-next-line */} { userId: u.userId, presenter: u.presenter, })); - const { data: hasPendingPollData, error, loading } = useSubscription( + const { data: hasPendingPollData, error, loading } = useDeduplicatedSubscription( hasPendingPoll, { variables: { userId: currentUserData?.userId }, @@ -339,12 +342,13 @@ const PollingGraphqlContainer: React.FC = () => { ); const [pollSubmitUserTypedVote] = useMutation(POLL_SUBMIT_TYPED_VOTE); const [pollSubmitUserVote] = useMutation(POLL_SUBMIT_VOTE); + const isPollingEnabled = useIsPollingEnabled(); const meetingData = hasPendingPollData && hasPendingPollData.meeting[0]; const pollData = meetingData && meetingData.polls[0]; const userData = pollData && pollData.users[0]; const pollExists = !!userData; - const showPolling = pollExists && !currentUserData?.presenter && Service.isPollingEnabled(); + const showPolling = pollExists && !currentUserData?.presenter && isPollingEnabled; const stackOptions = useMemo( () => !!pollData && Service.shouldStackOptions(pollData.options.map((o) => o.optionDesc)), [pollData], diff --git a/bigbluebutton-html5/imports/ui/components/polling/service.ts b/bigbluebutton-html5/imports/ui/components/polling/service.ts index 1fb128e4aa..2969b61821 100644 --- a/bigbluebutton-html5/imports/ui/components/polling/service.ts +++ b/bigbluebutton-html5/imports/ui/components/polling/service.ts @@ -1,15 +1,17 @@ import PollService from '/imports/ui/components/poll/service'; import AudioService from '/imports/ui/components/audio/service'; -import { isPollingEnabled } from '/imports/ui/services/features'; const MAX_CHAR_LENGTH = 5; -const APP_CONFIG = window.meetingClientSettings.public.app; export const shouldStackOptions = (keys: Array) => keys.some((k) => k.length > MAX_CHAR_LENGTH); -const playAlert = () => AudioService.playAlertSound( - `${APP_CONFIG.cdn + APP_CONFIG.basename + APP_CONFIG.instanceId}/resources/sounds/Poll.mp3`, -); +const playAlert = () => { + const APP_CONFIG = window.meetingClientSettings.public.app; + + return AudioService.playAlertSound( + `${APP_CONFIG.cdn + APP_CONFIG.basename}/resources/sounds/Poll.mp3`, + ); +}; export default { shouldStackOptions, @@ -17,5 +19,4 @@ export default { pollTypes: PollService.pollTypes, isDefaultPoll: PollService.isDefaultPoll, playAlert, - isPollingEnabled, }; diff --git a/bigbluebutton-html5/imports/ui/components/polling/styles.ts b/bigbluebutton-html5/imports/ui/components/polling/styles.ts index 64ee9125b2..0a554674a3 100644 --- a/bigbluebutton-html5/imports/ui/components/polling/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/polling/styles.ts @@ -33,11 +33,14 @@ import { import { hasPhoneDimentions } from '/imports/ui/stylesheets/styled-components/breakpoints'; import Button from '/imports/ui/components/common/button/component'; -const PollingTitle = styled.div` +const PollingTitle = styled.h1` white-space: nowrap; padding-bottom: ${mdPaddingY}; padding-top: ${mdPaddingY}; font-size: ${fontSizeSmall}; + margin: 0; + padding: 0; + font-weight: 600; `; const PollButtonWrapper = styled.div` @@ -133,8 +136,11 @@ const QHeader = styled.span` left: ${smPaddingY}; `; -const QTitle = styled.div` +const QTitle = styled.h1` font-size: ${fontSizeSmall}; + margin: 0; + padding: 0; + font-weight: 600; `; const QText = styled.div` diff --git a/bigbluebutton-html5/imports/ui/components/presence-adapter/component.tsx b/bigbluebutton-html5/imports/ui/components/presence-adapter/component.tsx index d5c922cd0f..7c94d1fe48 100644 --- a/bigbluebutton-html5/imports/ui/components/presence-adapter/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/presence-adapter/component.tsx @@ -1,7 +1,7 @@ import React, { useEffect } from 'react'; import useAuthData from '/imports/ui/core/local-states/useAuthData'; import Auth from '/imports/ui/services/auth'; -import { Session } from 'meteor/session'; +import Session from '/imports/ui/services/storage/in-memory'; interface PresenceAdapterProps { children: React.ReactNode; @@ -33,7 +33,7 @@ const PresenceAdapter: React.FC = ({ children }) => { meetingName, ); Auth.loggedIn = true; - Session.set('userWillAuth', false); + Session.setItem('userWillAuth', false); setAuthSetted(true); }, []); diff --git a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx index f1bc3472c0..6f0bae219c 100755 --- a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx @@ -5,7 +5,7 @@ import { HUNDRED_PERCENT, MAX_PERCENT } from '/imports/utils/slideCalcUtils'; import { SPACE } from '/imports/utils/keyCodes'; import { defineMessages, injectIntl } from 'react-intl'; import { toast } from 'react-toastify'; -import { Session } from 'meteor/session'; +import Session from '/imports/ui/services/storage/in-memory'; import PresentationToolbarContainer from './presentation-toolbar/container'; import PresentationMenu from './presentation-menu/container'; import DownloadPresentationButton from './download-presentation-button/component'; @@ -20,6 +20,8 @@ import browserInfo from '/imports/utils/browserInfo'; import { addAlert } from '../screenreader-alert/service'; import { debounce } from '/imports/utils/debounce'; import { throttle } from '/imports/utils/throttle'; +import LocatedErrorBoundary from '/imports/ui/components/common/error-boundary/located-error-boundary/component'; +import FallbackView from '/imports/ui/components/common/fallback-errors/fallback-view/component'; const intlMessages = defineMessages({ presentationLabel: { @@ -57,8 +59,6 @@ const FULLSCREEN_CHANGE_EVENT = isSafari ? 'webkitfullscreenchange' : 'fullscreenchange'; -const PAN_ZOOM_INTERVAL = window.meetingClientSettings.public.presentation.panZoomInterval || 200; - const getToolbarHeight = () => { let height = 0; const toolbarEl = document.getElementById('presentationToolbarWrapper'); @@ -85,6 +85,8 @@ class Presentation extends PureComponent { hadPresentation: false, }; + const PAN_ZOOM_INTERVAL = window.meetingClientSettings.public.presentation.panZoomInterval || 200; + this.currentPresentationToastId = null; this.getSvgRef = this.getSvgRef.bind(this); @@ -105,7 +107,7 @@ class Presentation extends PureComponent { this.renderCurrentPresentationToast = this.renderCurrentPresentationToast.bind(this); this.setPresentationRef = this.setPresentationRef.bind(this); this.setTldrawIsMounting = this.setTldrawIsMounting.bind(this); - Session.set('componentPresentationWillUnmount', false); + Session.setItem('componentPresentationWillUnmount', false); } static getDerivedStateFromProps(props, state) { @@ -185,6 +187,11 @@ class Presentation extends PureComponent { type: ACTIONS.SET_PRESENTATION_SLIDES_LENGTH, value: totalPages, }); + } else { + layoutContextDispatch({ + type: ACTIONS.SET_PRESENTATION_SLIDES_LENGTH, + value: 0, + }); } } @@ -296,7 +303,7 @@ class Presentation extends PureComponent { }, }); } - const presentationChanged = presentationId !== currentPresentationId; + const presentationChanged = presentationId && presentationId !== currentPresentationId; if ( !presentationIsOpen @@ -354,7 +361,7 @@ class Presentation extends PureComponent { } componentWillUnmount() { - Session.set('componentPresentationWillUnmount', true); + Session.setItem('componentPresentationWillUnmount', true); const { fullscreenContext, layoutContextDispatch } = this.props; window.removeEventListener('resize', this.onResize, false); @@ -401,7 +408,7 @@ class Presentation extends PureComponent { const presentationSizes = this.getPresentationSizesAvailable(); if (Object.keys(presentationSizes).length > 0) { // updating the size of the space available for the slide - if (!Session.get('componentPresentationWillUnmount')) { + if (!Session.getItem('componentPresentationWillUnmount')) { this.setState({ presentationHeight: presentationSizes.presentationHeight, presentationWidth: presentationSizes.presentationWidth, @@ -592,8 +599,10 @@ class Presentation extends PureComponent { fitToWidth, totalPages, userIsPresenter, + hasPoll, + currentPresentationPage, } = this.props; - const { zoom, isPanning } = this.state; + const { zoom, isPanning, tldrawAPI } = this.state; if (!currentSlide) return null; @@ -616,6 +625,8 @@ class Presentation extends PureComponent { layoutContextDispatch, presentationIsOpen, userIsPresenter, + currentPresentationPage, + tldrawAPI, }} setIsPanning={this.setIsPanning} isPanning={isPanning} @@ -632,6 +643,8 @@ class Presentation extends PureComponent { multiUser={multiUser} whiteboardId={currentSlide?.id} numberOfSlides={totalPages} + layoutSwapped={false} + hasPoll={hasPoll} /> ); } @@ -751,6 +764,7 @@ class Presentation extends PureComponent { isPanning, tldrawAPI, isToolbarVisible, + presentationWidth, } = this.state; let viewBoxDimensions; @@ -800,6 +814,8 @@ class Presentation extends PureComponent { const isVideoFocus = layoutType === LAYOUT_TYPE.VIDEO_FOCUS; const presentationZIndex = fullscreenContext ? presentationBounds.zIndex : undefined; + const APP_CRASH_METADATA = { logCode: 'whiteboard_crash', logMessage: 'Possible whiteboard crash' }; + return ( <> {!tldrawIsMounting + && presentationWidth > 0 && currentSlide && this.renderPresentationMenu()} - + + + {isFullscreen && }
- {!tldrawIsMounting && ( + {!tldrawIsMounting && presentationWidth > 0 && ( { this.refPresentationToolbar = ref; @@ -932,7 +951,7 @@ Presentation.propTypes = { presentationIsDownloadable: PropTypes.bool, presentationName: PropTypes.string, currentPresentationId: PropTypes.string, - presentationIsOpen: PropTypes.bool.isRequired, + presentationIsOpen: PropTypes.bool, totalPages: PropTypes.number.isRequired, publishedPoll: PropTypes.bool.isRequired, presentationBounds: PropTypes.shape({ @@ -974,4 +993,5 @@ Presentation.defaultProps = { presentationIsDownloadable: false, currentPresentationId: '', presentationName: '', + presentationIsOpen: true, }; diff --git a/bigbluebutton-html5/imports/ui/components/presentation/container.jsx b/bigbluebutton-html5/imports/ui/components/presentation/container.jsx index 6dc10853be..5a6ad38709 100755 --- a/bigbluebutton-html5/imports/ui/components/presentation/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/container.jsx @@ -4,6 +4,7 @@ import { notify } from '/imports/ui/services/notification'; import Presentation from '/imports/ui/components/presentation/component'; import Auth from '/imports/ui/services/auth'; import getFromUserSettings from '/imports/ui/services/users-settings'; +import { useMutation, useLazyQuery } from '@apollo/client'; import { layoutSelect, layoutSelectInput, @@ -12,7 +13,6 @@ import { } from '../layout/context'; import { DEVICE_TYPE } from '../layout/enums'; import MediaService from '../media/service'; -import { useSubscription, useMutation, useLazyQuery } from '@apollo/client'; import { CURRENT_PRESENTATION_PAGE_SUBSCRIPTION, CURRENT_PAGE_WRITERS_SUBSCRIPTION, @@ -22,21 +22,25 @@ import useMeeting from '/imports/ui/core/hooks/useMeeting'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; import { PRESENTATION_SET_ZOOM, PRESENTATION_SET_WRITERS } from './mutations'; import { GET_USER_IDS } from '/imports/ui/core/graphql/queries/users'; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; -const APP_CONFIG = window.meetingClientSettings.public.app; -const PRELOAD_NEXT_SLIDE = APP_CONFIG.preloadNextSlides; const fetchedpresentation = {}; const PresentationContainer = (props) => { - const { data: presentationPageData } = useSubscription(CURRENT_PRESENTATION_PAGE_SUBSCRIPTION); + const { data: presentationPageData } = useDeduplicatedSubscription( + CURRENT_PRESENTATION_PAGE_SUBSCRIPTION, + ); const { pres_page_curr: presentationPageArray } = (presentationPageData || {}); const currentPresentationPage = presentationPageArray && presentationPageArray[0]; const slideSvgUrl = currentPresentationPage && currentPresentationPage.svgUrl; - const { data: whiteboardWritersData } = useSubscription(CURRENT_PAGE_WRITERS_SUBSCRIPTION, { - variables: { pageId: currentPresentationPage?.pageId }, - skip: !currentPresentationPage?.pageId, - }); + const { data: whiteboardWritersData } = useDeduplicatedSubscription( + CURRENT_PAGE_WRITERS_SUBSCRIPTION, + { + variables: { pageId: currentPresentationPage?.pageId }, + skip: !currentPresentationPage?.pageId, + }, + ); const whiteboardWriters = whiteboardWritersData?.pres_page_writers || []; @@ -46,6 +50,9 @@ const PresentationContainer = (props) => { const [getUsers, { data: usersData }] = useLazyQuery(GET_USER_IDS, { fetchPolicy: 'no-cache' }); const users = usersData?.user || []; + const APP_CONFIG = window.meetingClientSettings.public.app; + const PRELOAD_NEXT_SLIDE = APP_CONFIG.preloadNextSlides; + const addWhiteboardGlobalAccess = () => { const usersIds = users.map((user) => user.userId); const { pageId } = currentPresentationPage; @@ -104,8 +111,9 @@ const PresentationContainer = (props) => { hasAccess: whiteboardWriters?.some((writer) => writer.userId === Auth.userID), }; - const { data: pollData } = useSubscription(POLL_SUBSCRIPTION); + const { data: pollData } = useDeduplicatedSubscription(POLL_SUBSCRIPTION); const poll = pollData?.poll[0] || {}; + const hasPoll = pollData?.poll?.length > 0; const currentSlide = currentPresentationPage ? { content: currentPresentationPage.content, @@ -117,6 +125,7 @@ const PresentationContainer = (props) => { num: currentPresentationPage?.num, presentationId: currentPresentationPage?.presentationId, svgUri: slideSvgUrl, + infiniteWhiteboard: currentPresentationPage.infiniteWhiteboard, } : null; let slidePosition; @@ -193,41 +202,43 @@ const PresentationContainer = (props) => { return ( ); @@ -236,5 +247,8 @@ const PresentationContainer = (props) => { export default PresentationContainer; PresentationContainer.propTypes = { - presentationIsOpen: PropTypes.bool.isRequired, + presentationIsOpen: PropTypes.bool, +}; +PresentationContainer.defaultProps = { + presentationIsOpen: true, }; diff --git a/bigbluebutton-html5/imports/ui/components/presentation/download-presentation-button/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/download-presentation-button/component.jsx index cc34c7a92d..aa22b35977 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/download-presentation-button/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/download-presentation-button/component.jsx @@ -18,14 +18,10 @@ const propTypes = { dark: PropTypes.bool, }; -const defaultProps = { - dark: false, -}; - const DownloadPresentationButton = ({ intl, handleDownloadPresentation, - dark, + dark = false, }) => ( { + const Settings = getSettingsSingletonInstance(); const { intl, - isFullscreen, - elementId, - elementName, - elementGroup, - currentElement, - currentGroup, - fullscreenRef, - tldrawAPI, + isFullscreen = false, + elementId = '', + elementName = '', + elementGroup = '', + currentElement = '', + currentGroup = '', + fullscreenRef = null, + tldrawAPI = null, handleToggleFullscreen, layoutContextDispatch, - meetingName, - isIphone, - isRTL, + meetingName = '', + isIphone = false, + isRTL = Settings.application.isRTL, isToolbarVisible, setIsToolbarVisible, - allowSnapshotOfCurrentSlide, + allowSnapshotOfCurrentSlide = false, presentationDropdownItems, slideNum, currentUser, whiteboardId, - persistShape + persistShape, } = props; const [state, setState] = useState({ @@ -152,7 +140,7 @@ const PresentationMenu = (props) => { ? intl.formatMessage(intlMessages.exitFullscreenLabel) : intl.formatMessage(intlMessages.fullscreenLabel) ); - + const formattedVisibilityLabel = (visible) => (visible ? intl.formatMessage(intlMessages.hideToolsDesc) : intl.formatMessage(intlMessages.showToolsDesc) @@ -198,9 +186,15 @@ const PresentationMenu = (props) => { const fileContent = e.target.result; const dataObj = extractShapes(JSON.parse(fileContent)); const dataArray = Object.values(dataObj); - dataArray.forEach(shape => { - shape.parentId = `page:${slideNum}`; - shape.meta.createdBy = currentUser.userId; + dataArray.forEach((originalShape) => { + const shape = { + ...originalShape, + parentId: `page:${slideNum}`, + meta: { + ...originalShape.meta, + createdBy: currentUser.userId, + }, + }; persistShape(shape, whiteboardId, currentUser.isModerator); }); }; @@ -211,14 +205,14 @@ const PresentationMenu = (props) => { } }; - const handleFileClick = () => { - const fileInput = document.getElementById('hiddenFileInput'); - if (fileInput) { - fileInput.click(); - } else { - console.error('File input not found'); - } - }; + // const handleFileClick = () => { + // const fileInput = document.getElementById('hiddenFileInput'); + // if (fileInput) { + // fileInput.click(); + // } else { + // console.error('File input not found'); + // } + // }; function renderToastContent() { const { loading, hasError } = state; @@ -310,20 +304,30 @@ const PresentationMenu = (props) => { try { // filter shapes that are inside the slide const backgroundShape = tldrawAPI.getCurrentPageShapes().find((s) => s.id === `shape:BG-${slideNum}`); - const shapes = tldrawAPI.getCurrentPageShapes().filter( - (shape) => shape.x <= backgroundShape.props.w - && shape.y <= backgroundShape.props.h - && shape.x >= 0 - && shape.y >= 0, + const shapes = tldrawAPI.getCurrentPageShapes(); + const pollShape = shapes.find((shape) => shape.type === 'poll'); + const svgElem = await tldrawAPI.getSvg( + shapes + .filter((shape) => shape.type !== 'poll') + .map((shape) => shape.id), ); - const svgElem = await tldrawAPI.getSvg(shapes.map((shape) => shape.id)); + svgElem.setAttribute('width', backgroundShape.props.w); + svgElem.setAttribute('height', backgroundShape.props.h); + svgElem.setAttribute('viewBox', `1 1 ${backgroundShape.props.w} ${backgroundShape.props.h}`); + if (pollShape) { + const pollShapeElement = document.getElementById(pollShape.id); + const pollShapeSvg = await toSvg(pollShapeElement); + const pollShapeImage = document.createElementNS('http://www.w3.org/2000/svg', 'image'); + pollShapeImage.setAttribute('href', pollShapeSvg); + pollShapeImage.setAttribute('width', pollShape.props.w); + pollShapeImage.setAttribute('height', pollShape.props.h); + pollShapeImage.setAttribute('x', pollShape.x); + pollShapeImage.setAttribute('y', pollShape.y); + svgElem.appendChild(pollShapeImage); + } // workaround for ios if (isIos || isSafari) { - svgElem.setAttribute('width', backgroundShape.props.w); - svgElem.setAttribute('height', backgroundShape.props.h); - svgElem.setAttribute('viewBox', `1 1 ${backgroundShape.props.w} ${backgroundShape.props.h}`); - const svgString = new XMLSerializer().serializeToString(svgElem); const blob = new Blob([svgString], { type: 'image/svg+xml' }); @@ -385,15 +389,15 @@ const PresentationMenu = (props) => { }, ); - if (props.amIPresenter) { - menuItems.push({ - key: 'list-item-load-shapes', - dataTest: 'loadShapes', - label: 'Load .tldr Data', - icon: 'pen_tool', - onClick: handleFileClick, - }); - } + // if (props.amIPresenter) { + // menuItems.push({ + // key: 'list-item-load-shapes', + // dataTest: 'loadShapes', + // label: 'Load .tldr Data', + // icon: 'pen_tool', + // onClick: handleFileClick, + // }); + // } presentationDropdownItems.forEach((item, index) => { switch (item.type) { @@ -454,7 +458,7 @@ const PresentationMenu = (props) => { } return ( - + @@ -467,7 +471,46 @@ const PresentationMenu = (props) => { setIsDropdownOpen((isOpen) => !isOpen); }} > - + + + )} @@ -495,6 +538,5 @@ const PresentationMenu = (props) => { }; PresentationMenu.propTypes = propTypes; -PresentationMenu.defaultProps = defaultProps; export default injectIntl(PresentationMenu); diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-menu/container.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-menu/container.jsx index d2e0d82e03..2b279075b3 100755 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-menu/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-menu/container.jsx @@ -1,13 +1,11 @@ -import React from 'react'; -import { useContext } from 'react'; +import React, { useContext } from 'react'; import PropTypes from 'prop-types'; import PresentationMenu from './component'; import FullscreenService from '/imports/ui/components/common/fullscreen-button/service'; import Auth from '/imports/ui/services/auth'; import { layoutSelect, layoutDispatch } from '/imports/ui/components/layout/context'; -import { isSnapshotOfCurrentSlideEnabled } from '/imports/ui/services/features'; +import { useIsSnapshotOfCurrentSlideEnabled } from '/imports/ui/services/features'; import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; -import { useSubscription } from '@apollo/client'; import { CURRENT_PAGE_WRITERS_SUBSCRIPTION, } from '/imports/ui/components/whiteboard/queries'; @@ -16,15 +14,17 @@ import useMeeting from '/imports/ui/core/hooks/useMeeting'; import { persistShape, } from '/imports/ui/components/whiteboard/service'; - +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const PresentationMenuContainer = (props) => { const fullscreen = layoutSelect((i) => i.fullscreen); const { element: currentElement, group: currentGroup } = fullscreen; const layoutContextDispatch = layoutDispatch(); - const { elementId } = props; + const { elementId, whiteboardId } = props; const isFullscreen = currentElement === elementId; - const isRTL = layoutSelect((i) => i.isRTL); + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application; const { pluginsExtensibleAreasAggregatedState } = useContext(PluginsContext); let presentationDropdownItems = []; if (pluginsExtensibleAreasAggregatedState.presentationDropdownItems) { @@ -33,7 +33,13 @@ const PresentationMenuContainer = (props) => { ]; } - const { data: whiteboardWritersData } = useSubscription(CURRENT_PAGE_WRITERS_SUBSCRIPTION); + const { data: whiteboardWritersData } = useDeduplicatedSubscription( + CURRENT_PAGE_WRITERS_SUBSCRIPTION, + { + variables: { pageId: whiteboardId }, + skip: !whiteboardId, + }, + ); const whiteboardWriters = whiteboardWritersData?.pres_page_writers || []; const hasWBAccess = whiteboardWriters?.some((writer) => writer.userId === Auth.userID); @@ -43,6 +49,7 @@ const PresentationMenuContainer = (props) => { const handleToggleFullscreen = (ref) => FullscreenService.toggleFullScreen(ref); const isIphone = !!(navigator.userAgent.match(/iPhone/i)); + const allowSnapshotOfCurrentSlide = useIsSnapshotOfCurrentSlideEnabled(); return ( { meetingName: meetingInfo?.name, handleToggleFullscreen, isIphone, - allowSnapshotOfCurrentSlide: isSnapshotOfCurrentSlideEnabled(), + allowSnapshotOfCurrentSlide, persistShape, }} /> diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-menu/styles.js b/bigbluebutton-html5/imports/ui/components/presentation/presentation-menu/styles.js index 709a903d3f..2b59006be4 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-menu/styles.js +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-menu/styles.js @@ -7,7 +7,7 @@ import { colorGrayDark, colorSuccess, colorGrayLightest, - colorWhite, + colorOffWhite, } from '/imports/ui/stylesheets/styled-components/palette'; import { borderSizeLarge, @@ -15,47 +15,53 @@ import { statusIconSize, borderSize, statusInfoHeight, - presentationMenuHeight, } from '/imports/ui/stylesheets/styled-components/general'; const DropdownButton = styled.button` - background-color: #FFF; + background-color: ${colorOffWhite}; border: none; - border-radius: 7px; - color: ${colorGrayDark}; + border-radius: 13px; + box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.16), + 0px 2px 3px rgba(0, 0, 0, 0.24), + 0px 2px 6px rgba(0, 0, 0, 0.1); + color: #2d2d2d; cursor: pointer; padding: .3rem .5rem; - padding-bottom: 6px; + display: flex; + align-items: center; + justify-content: center; tab-index: 0; &:hover { - background-color: #ececec; + background-color: ${colorGrayLightest}; } `; const Left = styled.div` cursor: pointer; position: absolute; - left: 0px; + left: 2px; + top: 2px; z-index: 999; - box-shadow: 0 4px 2px -2px rgba(0, 0, 0, 0.05); - border-bottom: 1px solid ${colorWhite}; - height: 44px; > div { - padding: 2px 4px 2px 4px; - background-color: ${colorWhite}; width: 50px; - height: 100%; + height: 40px; + display: flex; + align-items: center; + justify-content: center; } button { height: 100%; width: 100%; + display: flex; + align-items: center; + justify-content: center; } [dir="rtl"] & { - right: 0px; + right: 2px; left: auto; } `; diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toast/presentation-uploader-toast/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toast/presentation-uploader-toast/component.jsx index d4660a6683..51f09a3768 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toast/presentation-uploader-toast/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toast/presentation-uploader-toast/component.jsx @@ -5,8 +5,7 @@ import { toast } from 'react-toastify'; import { defineMessages } from 'react-intl'; import usePreviousValue from '/imports/ui/hooks/usePreviousValue'; import { notify } from '/imports/ui/services/notification'; - -const TIMEOUT_CLOSE_TOAST = 1; // second +import Session from '/imports/ui/services/storage/in-memory'; const EXPORT_STATUSES = { RUNNING: 'RUNNING', @@ -176,7 +175,7 @@ function renderPresentationItemStatus(item, intl) { return intl.formatMessage(errorMessage, constraint); } - if (('uploadErrorMsgKey' in item) && (item.uploadInProgress && item.uploadErrorMsgKey)) { + if (('uploadErrorMsgKey' in item) && item.uploadErrorMsgKey) { const errorMessage = intlMessages[item.uploadErrorMsgKey] || intlMessages.genericConversionStatus; @@ -239,7 +238,7 @@ function renderToastItem(item, intl) { { - if (hasError || isProcessing) Session.set('showUploadPresentationView', true); + if (hasError || isProcessing) Session.setItem('showUploadPresentationView', true); }} > @@ -431,23 +430,26 @@ function renderExportToast(presToShow, intl) { ); } -export const PresentationUploaderToast = ({intl, convertingPresentations, uploadingPresentations, presentations }) => { - const presentationsToConvert = convertingPresentations.concat(uploadingPresentations); +export const PresentationUploaderToast = ({ + intl, + convertingPresentations, + presentations, +}) => { const prevPresentations = usePreviousValue(presentations); useEffect(() => { presentations.forEach((p) => { - const prevPropPres = prevPresentations.find((pres) => pres.presentationId === p.presentationId); - + const prevPropPres = (prevPresentations || []) + .find((pres) => pres.presentationId === p.presentationId); // display notification when presentation is exported - let exportToastId = Session.get('presentationUploaderExportToastId'); + let exportToastId = Session.getItem('presentationUploaderExportToastId'); if (prevPropPres?.exportToChatStatus && p?.exportToChatStatus === EXPORT_STATUSES.EXPORTED && prevPropPres?.exportToChatStatus !== p?.exportToChatStatus ) { notify(intl.formatMessage(intlMessages.linkAvailable, { 0: p.name }), 'success'); - Session.set('presentationUploaderExportToastId', null); + Session.setItem('presentationUploaderExportToastId', null); handleDismissToast(exportToastId); } @@ -468,33 +470,35 @@ export const PresentationUploaderToast = ({intl, convertingPresentations, upload newestOnTop: true, closeOnClick: true, onClose: () => { - Session.set('presentationUploaderExportToastId', null); + Session.setItem('presentationUploaderExportToastId', null); }, }); - Session.set('presentationUploaderExportToastId', exportToastId); + Session.setItem('presentationUploaderExportToastId', exportToastId); } } }); }, [presentations]); - let activeToast = Session.get('presentationUploaderToastId'); - const showToast = presentationsToConvert.length > 0; + let activeToast = Session.getItem('presentationUploaderToastId'); + const showToast = convertingPresentations.length > 0; if (showToast && !activeToast) { - activeToast = toast.info(() => renderToastList(presentationsToConvert, intl), { + activeToast = toast.info(() => renderToastList(convertingPresentations, intl), { hideProgressBar: true, autoClose: false, newestOnTop: true, closeOnClick: true, className: 'presentationUploaderToast toastClass', + onClose: () => { + Session.setItem('presentationUploaderToastId', null); + }, }); - Session.set('presentationUploaderToastId', activeToast); + Session.setItem('presentationUploaderToastId', activeToast); } else if (!showToast && activeToast) { handleDismissToast(activeToast); - Session.set('presentationUploaderToastId', null); } else { toast.update(activeToast, { - render: renderToastList(presentationsToConvert, intl), + render: renderToastList(convertingPresentations, intl), }); } return null; diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toast/presentation-uploader-toast/container.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toast/presentation-uploader-toast/container.jsx index 84385f0a34..40e2032021 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toast/presentation-uploader-toast/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toast/presentation-uploader-toast/container.jsx @@ -1,25 +1,31 @@ import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; -import { UploadingPresentations } from '/imports/api/presentations'; import { PresentationUploaderToast } from './component'; -import { useSubscription } from '@apollo/client'; + import { EXPORTING_PRESENTATIONS_SUBSCRIPTION, } from '/imports/ui/components/whiteboard/queries'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const PresentationUploaderToastContainer = (props) => { - const { data: presentationData } = useSubscription(EXPORTING_PRESENTATIONS_SUBSCRIPTION); + const { + data: presentationData, + loading: presentationLoading, + } = useDeduplicatedSubscription( + EXPORTING_PRESENTATIONS_SUBSCRIPTION, + ); const presentations = presentationData?.pres_presentation || []; const convertingPresentations = presentations.filter( - (p) => !p.uploadCompleted || !!p.uploadErrorMsgKey, + (p) => (!p.uploadCompleted || !!p.uploadErrorMsgKey), ); + if (presentationLoading) return null; + if (!presentations.length) return null; return ( p), convertingPresentations, ...props, } @@ -28,10 +34,4 @@ const PresentationUploaderToastContainer = (props) => { ); }; -export default withTracker(() => { - const uploadingPresentations = UploadingPresentations.find({ $or: [{ 'upload.error': true }, { 'upload.done': false }] }).fetch(); - - return { - uploadingPresentations, - }; -})(PresentationUploaderToastContainer); +export default PresentationUploaderToastContainer; diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx index 06333f46b8..f7bb944e11 100755 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx @@ -89,6 +89,14 @@ const intlMessages = defineMessages({ id: 'app.whiteboard.toolbar.multiUserOff', description: 'Whiteboard toolbar turn multi-user off menu', }, + infiniteWhiteboardOn: { + id: 'app.whiteboard.toolbar.infiniteWhiteboardOn', + description: 'Whiteboard toolbar turn infinite wb on', + }, + infiniteWhiteboardOff: { + id: 'app.whiteboard.toolbar.infiniteWhiteboardOff', + description: 'Whiteboard toolbar turn infinite wb off', + }, pan: { id: 'app.whiteboard.toolbar.tools.hand', description: 'presentation toolbar pan label', @@ -120,7 +128,9 @@ class PresentationToolbar extends PureComponent { } componentDidUpdate(prevProps) { - const { zoom, setIsPanning, fitToWidth, fitToWidthHandler, currentSlideNum } = this.props; + const { + zoom, setIsPanning, fitToWidth, fitToWidthHandler, currentSlideNum, + } = this.props; const { wasFTWActive } = this.state; if (zoom <= HUNDRED_PERCENT && zoom !== prevProps.zoom && !fitToWidth) setIsPanning(); @@ -129,7 +139,7 @@ class PresentationToolbar extends PureComponent { setTimeout(() => { fitToWidthHandler(); this.setWasActive(false); - }, 150) + }, 150); } } @@ -137,10 +147,6 @@ class PresentationToolbar extends PureComponent { document.removeEventListener('keydown', this.switchSlide); } - setWasActive(wasFTWActive) { - this.setState({ wasFTWActive }); - } - handleFTWSlideChange() { const { fitToWidth, fitToWidthHandler } = this.props; if (fitToWidth) { @@ -150,9 +156,13 @@ class PresentationToolbar extends PureComponent { } handleSkipToSlideChange(event) { - const { skipToSlide } = this.props; + const { skipToSlide, currentSlide, setPresentationPageInfiniteWhiteboard } = this.props; const requestedSlideNum = Number.parseInt(event.target.value, 10); + const isInfiniteWhiteboard = currentSlide?.infiniteWhiteboard; + + if (isInfiniteWhiteboard) setPresentationPageInfiniteWhiteboard(false); + this.handleFTWSlideChange(); if (event) event.currentTarget.blur(); skipToSlide(requestedSlideNum); @@ -171,6 +181,10 @@ class PresentationToolbar extends PureComponent { return addWhiteboardGlobalAccess(whiteboardId); } + setWasActive(wasFTWActive) { + this.setState({ wasFTWActive }); + } + fullscreenToggleHandler() { const { fullscreenElementId, @@ -194,7 +208,12 @@ class PresentationToolbar extends PureComponent { } nextSlideHandler(event) { - const { nextSlide, endCurrentPoll } = this.props; + const { + nextSlide, endCurrentPoll, currentSlide, setPresentationPageInfiniteWhiteboard, + } = this.props; + const isInfiniteWhiteboard = currentSlide?.infiniteWhiteboard; + + if (isInfiniteWhiteboard) setPresentationPageInfiniteWhiteboard(false); this.handleFTWSlideChange(); if (event) event.currentTarget.blur(); @@ -203,7 +222,13 @@ class PresentationToolbar extends PureComponent { } previousSlideHandler(event) { - const { previousSlide, endCurrentPoll } = this.props; + const { + previousSlide, endCurrentPoll, currentSlide, setPresentationPageInfiniteWhiteboard, + } = this.props; + + const isInfiniteWhiteboard = currentSlide?.infiniteWhiteboard; + + if (isInfiniteWhiteboard) setPresentationPageInfiniteWhiteboard(false); this.handleFTWSlideChange(); if (event) event.currentTarget.blur(); @@ -256,7 +281,7 @@ class PresentationToolbar extends PureComponent { componentToReturn = (
); } @@ -573,6 +681,9 @@ ScreenshareComponent.propTypes = { intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, }).isRequired, + pluginScreenshareHelperItems: PropTypes.arrayOf(PropTypes.objectOf({ + position: PropTypes.string, + })).isRequired, isPresenter: PropTypes.bool.isRequired, layoutContextDispatch: PropTypes.func.isRequired, enableVolumeControl: PropTypes.bool.isRequired, diff --git a/bigbluebutton-html5/imports/ui/components/screenshare/container.jsx b/bigbluebutton-html5/imports/ui/components/screenshare/container.jsx index acb0cd7922..746bc080b3 100755 --- a/bigbluebutton-html5/imports/ui/components/screenshare/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/screenshare/container.jsx @@ -1,25 +1,24 @@ -import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; -import { useMutation, useSubscription } from '@apollo/client'; +import React, { useContext } from 'react'; +import { useMutation, useReactiveVar } from '@apollo/client'; +import { defineMessages } from 'react-intl'; import { getSharingContentType, - getBroadcastContentType, - isScreenGloballyBroadcasting, - isCameraAsContentGloballyBroadcasting, - isScreenBroadcasting, - isCameraAsContentBroadcasting, - shouldEnableVolumeControl, + useIsScreenGloballyBroadcasting, + useIsCameraAsContentGloballyBroadcasting, + useShouldEnableVolumeControl, + useIsScreenBroadcasting, + useIsCameraAsContentBroadcasting, + useScreenshareHasAudio, + useBroadcastContentType, } from './service'; +import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; import ScreenshareComponent from './component'; import { layoutSelect, layoutSelectOutput, layoutDispatch } from '../layout/context'; import getFromUserSettings from '/imports/ui/services/users-settings'; -import AudioService from '/imports/ui/components/audio/service'; -import MediaService from '/imports/ui/components/media/service'; -import { defineMessages } from 'react-intl'; import { EXTERNAL_VIDEO_STOP } from '../external-video-player/mutations'; import { PINNED_PAD_SUBSCRIPTION } from '../notes/queries'; - -const NOTES_CONFIG = window.meetingClientSettings.public.notes; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; +import AudioManager from '/imports/ui/services/audio-manager'; const screenshareIntlMessages = defineMessages({ // SCREENSHARE @@ -53,7 +52,7 @@ const screenshareIntlMessages = defineMessages({ endedDueToDataSaving: { id: 'app.media.screenshare.endDueToDataSaving', description: 'toast to show when a screenshare has ended by changing data savings option', - } + }, }); const cameraAsContentIntlMessages = defineMessages({ @@ -95,13 +94,18 @@ const ScreenshareContainer = (props) => { const screenShare = layoutSelectOutput((i) => i.screenShare); const fullscreen = layoutSelect((i) => i.fullscreen); const layoutContextDispatch = layoutDispatch(); + const { pluginsExtensibleAreasAggregatedState } = useContext(PluginsContext); const { element } = fullscreen; const fullscreenElementId = 'Screenshare'; const fullscreenContext = (element === fullscreenElementId); const [stopExternalVideoShare] = useMutation(EXTERNAL_VIDEO_STOP); - const { data: pinnedPadData } = useSubscription(PINNED_PAD_SUBSCRIPTION); + const { data: pinnedPadData } = useDeduplicatedSubscription(PINNED_PAD_SUBSCRIPTION); + + const NOTES_CONFIG = window.meetingClientSettings.public.notes; + const LAYOUT_CONFIG = window.meetingClientSettings.public.layout; + const isSharedNotesPinned = !!pinnedPadData && pinnedPadData.sharedNotes[0]?.sharedNotesExtId === NOTES_CONFIG.id; @@ -109,31 +113,44 @@ const ScreenshareContainer = (props) => { const info = { screenshare: { - icon: "desktop", + icon: 'desktop', locales: screenshareIntlMessages, startPreviewSizeBig: false, showSwitchPreviewSizeButton: true, }, camera: { - icon: "video", + icon: 'video', locales: cameraAsContentIntlMessages, startPreviewSizeBig: true, showSwitchPreviewSizeButton: false, }, }; - const getContentType = () => { - return isPresenter ? getSharingContentType() : getBroadcastContentType(); - } + const broadcastContentType = useBroadcastContentType(); + const getContentType = () => (isPresenter ? getSharingContentType() : broadcastContentType); const contentTypeInfo = info[getContentType()]; const defaultInfo = info.camera; - const selectedInfo = contentTypeInfo ? contentTypeInfo : defaultInfo; + const selectedInfo = contentTypeInfo || defaultInfo; + const outputDeviceId = useReactiveVar(AudioManager._outputDeviceId.value); + const screenIsGloballyBroadcasting = useIsScreenGloballyBroadcasting(); + const cameraAsContentIsGloballyBroadcasting = useIsCameraAsContentGloballyBroadcasting(); + const enableVolumeControl = useShouldEnableVolumeControl(); + const isScreenBroadcasting = useIsScreenBroadcasting(); + const isCameraAsContentBroadcasting = useIsCameraAsContentBroadcasting(); + const hasAudio = useScreenshareHasAudio(); - if (isScreenBroadcasting() || isCameraAsContentBroadcasting()) { + let pluginScreenshareHelperItems = []; + if (pluginsExtensibleAreasAggregatedState.screenshareHelperItems) { + pluginScreenshareHelperItems = [ + ...pluginsExtensibleAreasAggregatedState.screenshareHelperItems, + ]; + } + if (isScreenBroadcasting || isCameraAsContentBroadcasting) { return ( { fullscreenElementId, isSharedNotesPinned, stopExternalVideoShare, + outputDeviceId, + enableVolumeControl, + hasAudio, + isGloballyBroadcasting: screenIsGloballyBroadcasting + || cameraAsContentIsGloballyBroadcasting, + hidePresentationOnJoin: getFromUserSettings( + 'bbb_hide_presentation_on_join', + LAYOUT_CONFIG.hidePresentationOnJoin, + ), ...selectedInfo, } } @@ -150,14 +176,4 @@ const ScreenshareContainer = (props) => { return null; }; -const LAYOUT_CONFIG = window.meetingClientSettings.public.layout; - -export default withTracker(() => { - return { - isGloballyBroadcasting: isScreenGloballyBroadcasting() || isCameraAsContentGloballyBroadcasting(), - toggleSwapLayout: MediaService.toggleSwapLayout, - hidePresentationOnJoin: getFromUserSettings('bbb_hide_presentation_on_join', LAYOUT_CONFIG.hidePresentationOnJoin), - enableVolumeControl: shouldEnableVolumeControl(), - outputDeviceId: AudioService.outputDeviceId(), - }; -})(ScreenshareContainer); +export default ScreenshareContainer; diff --git a/bigbluebutton-html5/imports/ui/components/screenshare/plugin-button/component.tsx b/bigbluebutton-html5/imports/ui/components/screenshare/plugin-button/component.tsx new file mode 100644 index 0000000000..ce2df34a2a --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/screenshare/plugin-button/component.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import Styled from './styles'; + +interface PluginButtonComponentProps { + dark: boolean; + bottom: boolean; + right: boolean; + icon: string; + label: string; + onClick: () => void; +} + +const PluginButtonComponent = ({ + dark = false, + bottom = false, + onClick = () => {}, + right, + icon, + label, +}: PluginButtonComponentProps) => ( + + + +); + +export default PluginButtonComponent; diff --git a/bigbluebutton-html5/imports/ui/components/screenshare/plugin-button/container.tsx b/bigbluebutton-html5/imports/ui/components/screenshare/plugin-button/container.tsx new file mode 100644 index 0000000000..b2347a167b --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/screenshare/plugin-button/container.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import PluginButtonComponent from './component'; + +interface PluginButtonContainerProps { + dark: boolean; + bottom: boolean; + right: boolean; + icon: string; + label: string; + onClick: () => void; +} + +const PluginButtonContainer = (props: PluginButtonContainerProps) => { + const { + dark, + bottom, + right, + icon, + label, + onClick, + } = props; + return ( + + ); +}; + +export default PluginButtonContainer; diff --git a/bigbluebutton-html5/imports/ui/components/screenshare/plugin-button/styles.js b/bigbluebutton-html5/imports/ui/components/screenshare/plugin-button/styles.js new file mode 100644 index 0000000000..0532a8b329 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/screenshare/plugin-button/styles.js @@ -0,0 +1,64 @@ +import styled from 'styled-components'; +import { + colorWhite, + colorTransparent, + colorBlack, +} from '/imports/ui/stylesheets/styled-components/palette'; +import Button from '/imports/ui/components/common/button/component'; + +const PluginButtonWrapper = styled.div` + background-color: ${colorTransparent}; + cursor: pointer; + border: 0; + z-index: 2; + margin: 2px; + [dir="rtl"] & { + right: auto; + left: 0; + ${({ fullScreenEnabled }) => fullScreenEnabled && ` + left: 1.75rem; + `} + } + [class*="presentationZoomControls"] & { + position: relative !important; + } + + ${({ dark }) => dark && ` + background-color: rgba(0,0,0,.3); + + & button i { + color: ${colorWhite}; + } + `} + + ${({ dark }) => !dark && ` + background-color: ${colorTransparent}; + + & button i { + color: ${colorBlack}; + } + `} +`; + +const PluginButton = styled(Button)` + padding: 5px; + + &, + &:active, + &:hover, + &:focus { + background-color: ${colorTransparent} !important; + border: none !important; + + i { + border: none !important; + background-color: ${colorTransparent} !important; + font-size: 1rem; + } + } +`; + +export default { + PluginButtonWrapper, + PluginButton, +}; diff --git a/bigbluebutton-html5/imports/ui/components/components-data/screenshareGraphQlMiniMongoAdapter/queries.ts b/bigbluebutton-html5/imports/ui/components/screenshare/queries.ts similarity index 65% rename from bigbluebutton-html5/imports/ui/components/components-data/screenshareGraphQlMiniMongoAdapter/queries.ts rename to bigbluebutton-html5/imports/ui/components/screenshare/queries.ts index cb4c1d4a86..a42c3d80da 100644 --- a/bigbluebutton-html5/imports/ui/components/components-data/screenshareGraphQlMiniMongoAdapter/queries.ts +++ b/bigbluebutton-html5/imports/ui/components/screenshare/queries.ts @@ -1,12 +1,6 @@ import { gql } from '@apollo/client'; -export interface GetPresentationUploadTokenSubscriptionResponse { - data: { - screenshare: ScreenshareType[]; - }; -} - -export interface ScreenshareType { +export interface ScreenshareResponse { contentType: string; hasAudio: boolean; screenshareConf: string; @@ -19,8 +13,8 @@ export interface ScreenshareType { voiceConf: string; } -export const getScreenShareData = gql` - subscription getPresentationUploadToken { +export const SCREENSHARE_SUBSCRIPTION = gql` + subscription Screenshare { screenshare { contentType hasAudio @@ -37,5 +31,5 @@ export const getScreenShareData = gql` `; export default { - getScreenShareData, + SCREENSHARE_SUBSCRIPTION, }; diff --git a/bigbluebutton-html5/imports/ui/components/screenshare/service.js b/bigbluebutton-html5/imports/ui/components/screenshare/service.js index e5b45215d6..17eeb0cca4 100644 --- a/bigbluebutton-html5/imports/ui/components/screenshare/service.js +++ b/bigbluebutton-html5/imports/ui/components/screenshare/service.js @@ -1,78 +1,59 @@ -import Screenshare from '/imports/api/screenshare'; +import { makeVar, useReactiveVar } from '@apollo/client'; import KurentoBridge from '/imports/api/screenshare/client/bridge'; import BridgeService from '/imports/api/screenshare/client/bridge/service'; -import Settings from '/imports/ui/services/settings'; import logger from '/imports/startup/client/logger'; -import Auth from '/imports/ui/services/auth'; import AudioService from '/imports/ui/components/audio/service'; import MediaStreamUtils from '/imports/utils/media-stream-utils'; import ConnectionStatusService from '/imports/ui/components/connection-status/service'; import browserInfo from '/imports/utils/browserInfo'; +import createUseSubscription from '/imports/ui/core/hooks/createUseSubscription'; +import { SCREENSHARE_SUBSCRIPTION } from './queries'; -const VOLUME_CONTROL_ENABLED = window.meetingClientSettings.public.kurento.screenshare.enableVolumeControl; -const SCREENSHARE_MEDIA_ELEMENT_NAME = 'screenshareVideo'; +export const SCREENSHARE_MEDIA_ELEMENT_NAME = 'screenshareVideo'; -const DEFAULT_SCREENSHARE_STATS_TYPES = [ +export const DEFAULT_SCREENSHARE_STATS_TYPES = [ 'outbound-rtp', 'inbound-rtp', ]; -const CONTENT_TYPE_CAMERA = "camera"; -const CONTENT_TYPE_SCREENSHARE = "screenshare"; +export const CONTENT_TYPE_CAMERA = 'camera'; +export const CONTENT_TYPE_SCREENSHARE = 'screenshare'; -let _isSharingScreen = false; -const _isSharingDep = { - value: false, - tracker: new Tracker.Dependency(), -}; +export const isSharingVar = makeVar(false); +export const sharingContentTypeVar = makeVar(false); +export const cameraAsContentDeviceIdTypeVar = makeVar(''); -const _sharingContentTypeDep = { - value: false, - tracker: new Tracker.Dependency(), -}; +export const useScreenshare = createUseSubscription(SCREENSHARE_SUBSCRIPTION, {}, true); -const _cameraAsContentDeviceIdTypeDep = { - value: '', - tracker: new Tracker.Dependency(), -}; +export const useIsSharing = () => useReactiveVar(isSharingVar); +export const useSharingContentType = () => useReactiveVar(sharingContentTypeVar); +export const useCameraAsContentDeviceIdType = () => useReactiveVar(cameraAsContentDeviceIdTypeVar); -const isSharing = () => { - _isSharingDep.tracker.depend(); - return _isSharingDep.value; -}; +export const isSharing = () => isSharingVar(); -const setIsSharing = (isSharing) => { - if (_isSharingDep.value !== isSharing) { - _isSharingDep.value = isSharing; - _isSharingDep.tracker.changed(); +export const setIsSharing = (sharing) => { + if (isSharing() !== sharing) { + isSharingVar(sharing); } }; -const setSharingContentType = (contentType) => { - if (_sharingContentTypeDep.value !== contentType) { - _sharingContentTypeDep.value = contentType; - _sharingContentTypeDep.tracker.changed(); - } -} +export const getSharingContentType = () => sharingContentTypeVar(); -const getSharingContentType = () => { - _sharingContentTypeDep.tracker.depend(); - return _sharingContentTypeDep.value; -}; - -const getCameraAsContentDeviceId = () => { - _cameraAsContentDeviceIdTypeDep.tracker.depend(); - return _cameraAsContentDeviceIdTypeDep.value; -}; - -const setCameraAsContentDeviceId = (deviceId) => { - if (_cameraAsContentDeviceIdTypeDep.value !== deviceId) { - _cameraAsContentDeviceIdTypeDep.value = deviceId; - _cameraAsContentDeviceIdTypeDep.tracker.changed(); +export const setSharingContentType = (contentType) => { + if (getSharingContentType() !== contentType) { + sharingContentTypeVar(contentType); } }; -const _trackStreamTermination = (stream, handler) => { +export const getCameraAsContentDeviceId = () => cameraAsContentDeviceIdTypeVar(); + +export const setCameraAsContentDeviceId = (deviceId) => { + if (getCameraAsContentDeviceId() !== deviceId) { + cameraAsContentDeviceIdTypeVar(deviceId); + } +}; + +export const _trackStreamTermination = (stream, handler) => { if (typeof stream !== 'object' || typeof handler !== 'function') { throw new TypeError('Invalid trackStreamTermination arguments'); } @@ -109,94 +90,73 @@ const _trackStreamTermination = (stream, handler) => { } }; -const _isStreamActive = (stream) => { - const tracksAreActive = !stream.getTracks().some(track => track.readyState === 'ended'); +export const _isStreamActive = (stream) => { + const tracksAreActive = !stream.getTracks().some((track) => track.readyState === 'ended'); return tracksAreActive && stream.active; -} +}; -const _handleStreamTermination = () => { +export const _handleStreamTermination = () => { screenshareHasEnded(); }; -// A simplified, trackable version of isScreenBroadcasting that DOES NOT -// account for the presenter's local sharing state. -// It reflects the GLOBAL screen sharing state (akka-apps) -const isScreenGloballyBroadcasting = () => { - const screenshareEntry = Screenshare.findOne({ meetingId: Auth.meetingID, "screenshare.contentType": CONTENT_TYPE_SCREENSHARE }, - { fields: { 'screenshare.stream': 1 } }); +export const useIsScreenGloballyBroadcasting = () => { + const { data, loading } = useScreenshare(); - return (!screenshareEntry ? false : !!screenshareEntry.screenshare.stream); -} + return { + screenIsShared: Boolean( + data + && data[0] + && data[0].contentType === CONTENT_TYPE_SCREENSHARE + && data[0].stream, + ), + loading, + }; +}; -// A simplified, trackable version of isCameraContentBroadcasting that DOES NOT -// account for the presenter's local sharing state. -// It reflects the GLOBAL camera as content sharing state (akka-apps) -const isCameraAsContentGloballyBroadcasting = () => { - const cameraAsContentEntry = Screenshare.findOne({ meetingId: Auth.meetingID, "screenshare.contentType": CONTENT_TYPE_CAMERA }, - { fields: { 'screenshare.stream': 1 } }); +export const useIsCameraAsContentGloballyBroadcasting = () => { + const { data } = useScreenshare(); - return (!cameraAsContentEntry ? false : !!cameraAsContentEntry.screenshare.stream); -} + return Boolean(data && data[0] && data[0].contentType === CONTENT_TYPE_CAMERA && data[0].stream); +}; -// when the meeting information has been updated check to see if it was -// screensharing. If it has changed either trigger a call to receive video -// and display it, or end the call and hide the video -const isScreenBroadcasting = () => { - const sharing = isSharing() && getSharingContentType() == CONTENT_TYPE_SCREENSHARE; - const screenshareEntry = Screenshare.findOne({ meetingId: Auth.meetingID, "screenshare.contentType": CONTENT_TYPE_SCREENSHARE }, - { fields: { 'screenshare.stream': 1 } }); - const screenIsShared = !screenshareEntry ? false : !!screenshareEntry.screenshare.stream; - - if (screenIsShared && isSharing) { - setIsSharing(false); - } +export const useIsScreenBroadcasting = () => { + const active = useIsSharing(); + const sharingContentType = useSharingContentType(); + const { screenIsShared } = useIsScreenGloballyBroadcasting(); + const sharing = active && sharingContentType === CONTENT_TYPE_SCREENSHARE; return sharing || screenIsShared; }; -// when the meeting information has been updated check to see if it was -// sharing camera as content. If it has changed either trigger a call to receive video -// and display it, or end the call and hide the video -const isCameraAsContentBroadcasting = () => { - const sharing = isSharing() && getSharingContentType() === CONTENT_TYPE_CAMERA; - const screenshareEntry = Screenshare.findOne({ meetingId: Auth.meetingID, "screenshare.contentType": CONTENT_TYPE_CAMERA }, - { fields: { 'screenshare.stream': 1 } }); - const cameraAsContentIsShared = !screenshareEntry ? false : !!screenshareEntry.screenshare.stream; - - if (cameraAsContentIsShared && isSharing) { - setIsSharing(false); - } +export const useIsCameraAsContentBroadcasting = () => { + const active = useIsSharing(); + const sharingContentType = useSharingContentType(); + const sharing = active && sharingContentType === CONTENT_TYPE_CAMERA; + const cameraAsContentIsShared = useIsCameraAsContentGloballyBroadcasting(); return sharing || cameraAsContentIsShared; }; +export const useScreenshareHasAudio = () => { + const { data } = useScreenshare(); -const screenshareHasAudio = () => { - const screenshareEntry = Screenshare.findOne({ meetingId: Auth.meetingID }, - { fields: { 'screenshare.hasAudio': 1 } }); + return Boolean(data && data[0] && data[0].hasAudio); +}; - if (!screenshareEntry) { - return false; - } +export const useBroadcastContentType = () => { + const { data } = useScreenshare(); - return !!screenshareEntry.screenshare.hasAudio; -} - -const getBroadcastContentType = () => { - const screenshareEntry = Screenshare.findOne({meetindId: Auth.meedingID}, - { fields: { 'screenshare.contentType': 1} }); - - if (!screenshareEntry) { + if (!data || !data[0]) { // defaults to contentType: "camera" return CONTENT_TYPE_CAMERA; } - return screenshareEntry.screenshare.contentType; -} + return data[0].contentType; +}; -const screenshareHasEnded = () => { - if (isSharing()) { +export const screenshareHasEnded = () => { + if (isSharingVar()) { setIsSharing(false); } if (getSharingContentType() === CONTENT_TYPE_CAMERA) { @@ -206,11 +166,9 @@ const screenshareHasEnded = () => { KurentoBridge.stop(); }; -const getMediaElement = () => { - return document.getElementById(SCREENSHARE_MEDIA_ELEMENT_NAME); -} +export const getMediaElement = () => document.getElementById(SCREENSHARE_MEDIA_ELEMENT_NAME); -const getMediaElementDimensions = () => { +export const getMediaElementDimensions = () => { const element = getMediaElement(); return { width: element?.videoWidth ?? 0, @@ -218,16 +176,22 @@ const getMediaElementDimensions = () => { }; }; -const setVolume = (volume) => { +export const setVolume = (volume) => { KurentoBridge.setVolume(volume); }; -const getVolume = () => KurentoBridge.getVolume(); +export const getVolume = () => KurentoBridge.getVolume(); -const shouldEnableVolumeControl = () => VOLUME_CONTROL_ENABLED && screenshareHasAudio(); +export const useShouldEnableVolumeControl = () => { + const SCREENSHARE_CONFIG = window.meetingClientSettings.public.kurento.screenshare; + const VOLUME_CONTROL_ENABLED = SCREENSHARE_CONFIG.enableVolumeControl; + const hasAudio = useScreenshareHasAudio(); -const attachLocalPreviewStream = (mediaElement) => { - const {isTabletApp} = browserInfo; + return VOLUME_CONTROL_ENABLED && hasAudio; +}; + +export const attachLocalPreviewStream = (mediaElement) => { + const { isTabletApp } = browserInfo; if (isTabletApp) { // We don't show preview for mobile app, as the stream is only available in native code return; @@ -239,7 +203,7 @@ const attachLocalPreviewStream = (mediaElement) => { } }; -const setOutputDeviceId = (outputDeviceId) => { +export const setOutputDeviceId = (outputDeviceId) => { const screenShareElement = document.getElementById(SCREENSHARE_MEDIA_ELEMENT_NAME); const sinkIdSupported = screenShareElement && typeof screenShareElement.setSinkId === 'function'; const srcStream = screenShareElement?.srcObject; @@ -270,15 +234,21 @@ const setOutputDeviceId = (outputDeviceId) => { } }; -const screenshareHasStarted = (isPresenter, options = {}) => { +export const screenshareHasStarted = (hasAudio, isPresenter, options = {}) => { // Presenter's screen preview is local, so skip if (!isPresenter) { - viewScreenshare({ outputDeviceId: options.outputDeviceId }); + viewScreenshare({ outputDeviceId: options.outputDeviceId }, hasAudio); } }; -const shareScreen = async (stopWatching, isPresenter, onFail, options = {}) => { - if (isCameraAsContentBroadcasting()) { +export const shareScreen = async ( + isCameraAsContentBroadcasting, + stopWatching, + isPresenter, + onFail, + options = {}, +) => { + if (isCameraAsContentBroadcasting) { screenshareHasEnded(); } @@ -317,8 +287,7 @@ const shareScreen = async (stopWatching, isPresenter, onFail, options = {}) => { } }; -const viewScreenshare = (options = {}) => { - const hasAudio = screenshareHasAudio(); +export const viewScreenshare = (options = {}, hasAudio) => { KurentoBridge.view({ hasAudio, outputDeviceId: options.outputDeviceId }) .catch((error) => { logger.error({ @@ -331,14 +300,11 @@ const viewScreenshare = (options = {}) => { }); }; -const screenShareEndAlert = () => AudioService +export const screenShareEndAlert = () => AudioService .playAlertSound(`${window.meetingClientSettings.public.app.cdn - + window.meetingClientSettings.public.app.basename - + window.meetingClientSettings.public.app.instanceId}` + + window.meetingClientSettings.public.app.basename}` + '/resources/sounds/ScreenshareOff.mp3'); -const dataSavingSetting = () => Settings.dataSaving.viewScreenshare; - /** * Get stats about all active screenshare peers. * @@ -357,7 +323,7 @@ const dataSavingSetting = () => Settings.dataSaving.viewScreenshare; * peerIdString: RTCStatsReport * } */ -const getStats = async (statsTypes = DEFAULT_SCREENSHARE_STATS_TYPES) => { +export const getStats = async (statsTypes = DEFAULT_SCREENSHARE_STATS_TYPES) => { const screenshareStats = {}; const peer = KurentoBridge.getPeerConnection(); @@ -375,7 +341,7 @@ const getStats = async (statsTypes = DEFAULT_SCREENSHARE_STATS_TYPES) => { }; // This method may throw errors -const isMediaFlowing = (previousStats, currentStats) => { +export const isMediaFlowing = (previousStats, currentStats) => { const bpsData = ConnectionStatusService.calculateBitsPerSecond( currentStats?.screenshareStats, previousStats?.screenshareStats, @@ -386,18 +352,13 @@ const isMediaFlowing = (previousStats, currentStats) => { return bpsDataAggr > 0; }; -export { +export default { SCREENSHARE_MEDIA_ELEMENT_NAME, isMediaFlowing, - isScreenBroadcasting, - isCameraAsContentBroadcasting, screenshareHasEnded, screenshareHasStarted, - screenshareHasAudio, - getBroadcastContentType, shareScreen, screenShareEndAlert, - dataSavingSetting, isSharing, setIsSharing, setSharingContentType, @@ -405,13 +366,20 @@ export { getMediaElement, getMediaElementDimensions, attachLocalPreviewStream, - isScreenGloballyBroadcasting, - isCameraAsContentGloballyBroadcasting, getStats, setVolume, getVolume, - shouldEnableVolumeControl, setCameraAsContentDeviceId, getCameraAsContentDeviceId, setOutputDeviceId, + useCameraAsContentDeviceIdType, + useIsSharing, + useSharingContentType, + useIsScreenGloballyBroadcasting, + useIsCameraAsContentGloballyBroadcasting, + useShouldEnableVolumeControl, + useIsScreenBroadcasting, + useIsCameraAsContentBroadcasting, + useScreenshareHasAudio, + useBroadcastContentType, }; diff --git a/bigbluebutton-html5/imports/ui/components/screenshare/styles.js b/bigbluebutton-html5/imports/ui/components/screenshare/styles.js index b5f948aa68..949d3e1ecb 100644 --- a/bigbluebutton-html5/imports/ui/components/screenshare/styles.js +++ b/bigbluebutton-html5/imports/ui/components/screenshare/styles.js @@ -90,7 +90,37 @@ const HoverToolbar = styled.div` `} `; +const ScreenshareButtonsContainterWrapper = styled.div` + position: absolute; + z-index: 2; + display: flex; + width: 50%; + + ${({ positionXAxis }) => positionXAxis === 'right' && ` + right: 0; + flex-direction: row-reverse; + `} + ${({ positionXAxis }) => positionXAxis === 'left' && ` + left: 0; + `} + + ${({ positionYAxis }) => positionYAxis === 'top' && ` + top: 0; + `} + ${({ positionYAxis }) => positionYAxis === 'bottom' && ` + bottom: 0; + `} +`; + +const FullscreenButtonWrapperForScreenshare = styled.div` + & > * { + position: relative !important; + } +`; + export default { + FullscreenButtonWrapperForScreenshare, + ScreenshareButtonsContainterWrapper, ScreenshareContainerInside, MainText, ScreenshareVideo, diff --git a/bigbluebutton-html5/imports/ui/components/screenshare/switch-button/component.jsx b/bigbluebutton-html5/imports/ui/components/screenshare/switch-button/component.jsx index e7bf4ab467..fedf4f8ed1 100644 --- a/bigbluebutton-html5/imports/ui/components/screenshare/switch-button/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/screenshare/switch-button/component.jsx @@ -24,21 +24,13 @@ const propTypes = { switched: PropTypes.bool, }; -const defaultProps = { - dark: false, - bottom: false, - handleSwitch: () => {}, - switched: false, -}; - -const SwitchButtonComponent = (props) => { - const { - intl, - dark, - bottom, - handleSwitch, - switched, - } = props; +const SwitchButtonComponent = ({ + intl, + dark = false, + bottom = false, + handleSwitch = () => {}, + switched = false, +}) => { const formattedLabel = intl.formatMessage(switched ? intlMessages.switchButtonShrink : intlMessages.switchButtonExpand); @@ -59,6 +51,5 @@ const SwitchButtonComponent = (props) => { }; SwitchButtonComponent.propTypes = propTypes; -SwitchButtonComponent.defaultProps = defaultProps; export default injectIntl(SwitchButtonComponent); diff --git a/bigbluebutton-html5/imports/ui/components/screenshare/switch-button/styles.js b/bigbluebutton-html5/imports/ui/components/screenshare/switch-button/styles.js index 94f1c68fb1..42821cfb27 100644 --- a/bigbluebutton-html5/imports/ui/components/screenshare/switch-button/styles.js +++ b/bigbluebutton-html5/imports/ui/components/screenshare/switch-button/styles.js @@ -7,7 +7,7 @@ import { import Button from '/imports/ui/components/common/button/component'; const SwitchButtonWrapper = styled.div` - position: absolute; + position: relative; right: 0; left: auto; background-color: ${colorTransparent}; diff --git a/bigbluebutton-html5/imports/ui/components/settings-loader/component.tsx b/bigbluebutton-html5/imports/ui/components/settings-loader/component.tsx index 95255136f9..c2e67c80a1 100644 --- a/bigbluebutton-html5/imports/ui/components/settings-loader/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/settings-loader/component.tsx @@ -1,15 +1,18 @@ -import React, { useContext, useEffect } from 'react'; -import { setMeetingSettings } from '../../core/local-states/useMeetingSettings'; -import MeetingClientSettings from '../../Types/meetingClientSettings'; -import ClientStartup from '/client/clientStartup'; -import { LoadingContext } from '../common/loading-screen/loading-screen-HOC/component'; -import CustomUsersSettings from '../join-handler/custom-users-settings/component'; -import logger from '/imports/startup/client/logger'; +import React, { useEffect } from 'react'; +import { v4 as uuid } from 'uuid'; +import { setMeetingSettings } from '/imports/ui/core/local-states/useMeetingSettings'; +import MeetingClientSettings from '/imports/ui/Types/meetingClientSettings'; +import { ErrorScreen } from '/imports/ui/components/error-screen/component'; +import LoadingScreen from '/imports/ui/components/common/loading-screen/component'; +import Session from '/imports/ui/services/storage/in-memory'; +import BBBWeb from '/imports/api/bbb-web-api'; + +const connectionTimeout = 60000; interface Response { meeting_clientSettings: Array<{ clientSettingsJson: MeetingClientSettings, - }> + }>; } declare global { @@ -18,43 +21,86 @@ declare global { } } -const SettingsLoader: React.FC = () => { - const [allowToRender, setAllowToRender] = React.useState(false); - const loadingContextInfo = useContext(LoadingContext); - useEffect(() => { - logger.info('Fetching settings'); - loadingContextInfo.setLoading(true, '3/4'); - }, []); +interface SettingsLoaderProps { + children: React.ReactNode; +} + +const SettingsLoader: React.FC = (props) => { + const { children } = props; + const [settingsFetched, setSettingsFetched] = React.useState(false); + const [error, setError] = React.useState(null); + const [loading, setLoading] = React.useState(false); + const timeoutRef = React.useRef>(); useEffect(() => { + setLoading(true); + + const controller = new AbortController(); + timeoutRef.current = setTimeout(() => { + controller.abort(); + setError('Timeout fetching client settings'); + setLoading(false); + }, connectionTimeout); + + const clientSessionUUID = uuid(); + sessionStorage.setItem('clientSessionUUID', clientSessionUUID); + const urlParams = new URLSearchParams(window.location.search); const sessionToken = urlParams.get('sessionToken'); - const clientStartupSettings = `/api/rest/clientSettings/?sessionToken=${sessionToken}`; - const url = new URL(`${window.location.origin}${clientStartupSettings}`); - fetch(url, { method: 'get' }) - .then((resp) => resp.json()) - .then((data: Response) => { - const settings = data?.meeting_clientSettings[0].clientSettingsJson; - window.meetingClientSettings = JSON.parse(JSON.stringify(settings as unknown as MeetingClientSettings)); - const Meteor = { settings: {} }; - Meteor.settings = window.meetingClientSettings; - setMeetingSettings(settings as unknown as MeetingClientSettings); - setAllowToRender(true); - }).catch(() => { - loadingContextInfo.setLoading(false, ''); - throw new Error('Error on requesting client settings data.'); + if (!sessionToken) { + setLoading(false); + setError('Missing session token'); + return; + } + + BBBWeb.index(controller.signal) + .then(({ data }) => { + const url = new URL(`${data.graphqlApiUrl}/clientSettings`); + fetch(url, { + method: 'get', + credentials: 'include', + headers: { + 'x-session-token': sessionToken ?? '', + }, + signal: controller.signal, + }) + .then((resp) => resp.json()) + .then((data: Response) => { + clearTimeout(timeoutRef.current); + const settings = data?.meeting_clientSettings[0].clientSettingsJson; + window.meetingClientSettings = JSON.parse(JSON.stringify(settings)); + setMeetingSettings(settings); + setLoading(false); + setSettingsFetched(true); + }).catch(() => { + setLoading(false); + setError('Error fetching client settings'); + Session.setItem('errorMessageDescription', 'meeting_ended'); + }); + }).catch((error) => { + setLoading(false); + setError('Error fetching GraphQL URL: '.concat(error.message || '')); }); - // } }, []); + return ( - (allowToRender) - ? ( - - - - ) - : null + <> + {settingsFetched ? children : null} + {error ? ( + + ) : null} + {loading ? ( + +
+ Loading... +
+
+ ) : null} + ); }; diff --git a/bigbluebutton-html5/imports/ui/components/settings/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/component.jsx index c374548253..4485ac0ec8 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/component.jsx @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import ModalFullscreen from '/imports/ui/components/common/modal/fullscreen/component'; import { defineMessages, injectIntl } from 'react-intl'; +import Langmap from 'langmap'; import DataSaving from '/imports/ui/components/settings/submenus/data-saving/component'; import Application from '/imports/ui/components/settings/submenus/application/component'; import Notification from '/imports/ui/components/settings/submenus/notification/component'; @@ -9,6 +10,7 @@ import PropTypes from 'prop-types'; import Styled from './styles'; import { formatLocaleCode } from '/imports/utils/string-utils'; import { setUseCurrentLocale } from '../../core/local-states/useCurrentLocale'; +import Transcription from '/imports/ui/components/settings/submenus/transcription/component'; const intlMessages = defineMessages({ appTabLabel: { @@ -67,6 +69,10 @@ const intlMessages = defineMessages({ id: 'app.switch.offLabel', description: 'label for toggle switch off state', }, + transcriptionLabel: { + id: 'app.settings.transcriptionTab.label', + description: 'label for transcriptions tab', + }, }); const propTypes = { @@ -96,6 +102,15 @@ const propTypes = { availableLocales: PropTypes.objectOf(PropTypes.array).isRequired, showToggleLabel: PropTypes.bool.isRequired, isReactionsEnabled: PropTypes.bool.isRequired, + transcription: PropTypes.shape({ + partialUtterances: PropTypes.bool, + minUtteraceLength: PropTypes.number, + }).isRequired, + isGladiaEnabled: PropTypes.bool.isRequired, + fallbackLocales: PropTypes.objectOf(PropTypes.shape({ + englishName: PropTypes.string.isRequired, + nativeName: PropTypes.string.isRequired, + })).isRequired, }; class Settings extends Component { @@ -107,13 +122,14 @@ class Settings extends Component { super(props); const { - dataSaving, application, selectedTab, + dataSaving, application, selectedTab, transcription, } = props; this.state = { current: { dataSaving: clone(dataSaving), application: clone(application), + transcription: clone(transcription), }, saved: { dataSaving: clone(dataSaving), @@ -131,10 +147,29 @@ class Settings extends Component { } componentDidMount() { - const { availableLocales } = this.props; + const { availableLocales, fallbackLocales } = this.props; availableLocales.then((locales) => { - this.setState({ allLocales: locales.filter((locale) => locale?.name !== 'index') }); + const tempAggregateLocales = locales + .map((file) => file.name) + .map((file) => file.replace('.json', '')) + .map((file) => file.replace('_', '-')) + .map((locale) => { + const localeName = (Langmap[locale] || {}).nativeName + || (fallbackLocales[locale] || {}).nativeName + || locale; + return { + locale, + name: localeName, + }; + }) + .reverse() + .filter((item, index, self) => index === self.findIndex((i) => ( + i.name === item.name + ))) + .reverse(); + + this.setState({ allLocales: tempAggregateLocales }); }); } @@ -176,6 +211,9 @@ class Settings extends Component { isScreenSharingEnabled, isVideoEnabled, isReactionsEnabled, + isGladiaEnabled, + paginationToggleEnabled, + isChatEnabled, } = this.props; const { @@ -217,6 +255,17 @@ class Settings extends Component { ) : null} + {isGladiaEnabled + ? ( + + + {intl.formatMessage(intlMessages.transcriptionLabel)} + + ) + : null} @@ -238,6 +288,7 @@ class Settings extends Component { showGuestNotification={showGuestNotification} showToggleLabel={showToggleLabel} displaySettingsStatus={this.displaySettingsStatus} + isChatEnabled={isChatEnabled} {...{ isModerator }} /> @@ -255,6 +306,17 @@ class Settings extends Component { ) : null} + {isGladiaEnabled + ? ( + + + + ) + : null} ); } diff --git a/bigbluebutton-html5/imports/ui/components/settings/container.jsx b/bigbluebutton-html5/imports/ui/components/settings/container.jsx index 663db15dd7..82809cbb08 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/container.jsx @@ -1,45 +1,76 @@ import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; -import SettingsService from '/imports/ui/services/settings'; import Settings from './component'; import { layoutDispatch } from '../layout/context'; -import { isScreenSharingEnabled } from '/imports/ui/services/features'; +import { useIsChatEnabled, useIsScreenSharingEnabled } from '/imports/ui/services/features'; import UserReactionService from '/imports/ui/components/user-reaction/service'; +import AudioCaptionsService from '/imports/ui/components/audio/audio-graphql/audio-captions/service'; import { - getUserRoles, - isPresenter, - showGuestNotification, updateSettings, getAvailableLocales, + FALLBACK_LOCALES, } from './service'; import useUserChangedLocalSettings from '../../services/settings/hooks/useUserChangedLocalSettings'; +import { useShouldRenderPaginationToggle } from '/imports/ui/components/video-provider/hooks'; +import useSettings from '/imports/ui/services/settings/hooks/useSettings'; +import { SETTINGS } from '/imports/ui/services/settings/enums'; +import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; +import useMeeting from '/imports/ui/core/hooks/useMeeting'; + +const ASK_MODERATOR = 'ASK_MODERATOR'; const SettingsContainer = (props) => { const layoutContextDispatch = layoutDispatch(); const setLocalSettings = useUserChangedLocalSettings(); + const paginationToggleEnabled = useShouldRenderPaginationToggle(); + const { data: currentUser } = useCurrentUser((u) => ({ + presenter: u.presenter, + isModerator: u.isModerator, + })); + const { data: meeting } = useMeeting((m) => ({ + usersPolicies: { + guestPolicy: m.usersPolicies.guestPolicy, + }, + })); + const application = useSettings(SETTINGS.APPLICATION); + const audio = useSettings(SETTINGS.AUDIO); + const dataSaving = useSettings(SETTINGS.DATA_SAVING); + const transcription = useSettings(SETTINGS.TRANSCRIPTION); + const availableLocales = getAvailableLocales(); + const isPresenter = currentUser?.presenter ?? false; + const isModerator = currentUser?.isModerator ?? false; + const isScreenSharingEnabled = useIsScreenSharingEnabled(); + const showGuestNotification = meeting?.usersPolicies?.guestPolicy === ASK_MODERATOR; + const isReactionsEnabled = UserReactionService.useIsEnabled(); + const isGladiaEnabled = AudioCaptionsService.isGladia(); + const isChatEnabled = useIsChatEnabled(); return ( ); }; -export default withTracker((props) => ({ - ...props, - audio: SettingsService.audio, - dataSaving: SettingsService.dataSaving, - application: SettingsService.application, - updateSettings, - availableLocales: getAvailableLocales(), - isPresenter: isPresenter(), - isModerator: getUserRoles() === 'MODERATOR', - showGuestNotification: showGuestNotification(), - showToggleLabel: false, - isScreenSharingEnabled: isScreenSharingEnabled(), - isVideoEnabled: window.meetingClientSettings.public.kurento.enableVideo, - isReactionsEnabled: UserReactionService.isEnabled(), -}))(SettingsContainer); +export default SettingsContainer; diff --git a/bigbluebutton-html5/imports/ui/components/settings/service.js b/bigbluebutton-html5/imports/ui/components/settings/service.js index f90e8c8de9..e345d69654 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/service.js +++ b/bigbluebutton-html5/imports/ui/components/settings/service.js @@ -1,61 +1,65 @@ -import Users from '/imports/api/users'; -import Auth from '/imports/ui/services/auth'; -import Settings from '/imports/ui/services/settings'; -import {notify} from '/imports/ui/services/notification'; -import GuestService from '/imports/ui/components/waiting-users/service'; -import Intl from '/imports/ui/services/locale'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; +import { notify } from '/imports/ui/services/notification'; +import intlHolder from '../../core/singletons/intlHolder'; -const getUserRoles = () => { - const user = Users.findOne({ - userId: Auth.userID, - }); +export const isKeepPushingLayoutEnabled = () => window.meetingClientSettings.public.layout.showPushLayoutToggle; - return user?.role; -}; - -const isPresenter = () => { - const user = Users.findOne({ - userId: Auth.userID, - }); - - return user?.presenter; -}; - -const showGuestNotification = () => { - const guestPolicy = GuestService.getGuestPolicy(); - - // Guest notification only makes sense when guest - // entrance is being controlled by moderators - return guestPolicy === 'ASK_MODERATOR'; -}; - -const isKeepPushingLayoutEnabled = () => window.meetingClientSettings.public.layout.showPushLayoutToggle; - -const updateSettings = (obj, msgDescriptor, mutation) => { +export const updateSettings = (obj, msgDescriptor, mutation) => { + const Settings = getSettingsSingletonInstance(); Object.keys(obj).forEach(k => (Settings[k] = obj[k])); Settings.save(mutation); if (msgDescriptor) { // prevents React state update on unmounted component setTimeout(() => { - Intl.formatMessage(msgDescriptor).then((txt) => { - notify( - txt, - 'info', - 'settings', - ); - }); + const intl = intlHolder.getIntl(); + notify( + intl.formatMessage(msgDescriptor), + 'info', + 'settings', + ); }, 0); } }; -const getAvailableLocales = () => fetch('./locale-list').then(locales => locales.json()); +export const getAvailableLocales = () => fetch('./locales/') + .then((locales) => locales.json()) + .then((locales) => locales.filter((locale) => locale.name !== 'index.json')); -export { - getUserRoles, - isPresenter, - showGuestNotification, +export const FALLBACK_LOCALES = { + dv: { + englishName: 'Dhivehi', + nativeName: 'ދިވެހި', + }, + hy: { + englishName: 'Armenian', + nativeName: 'Հայերեն', + }, + ka: { + englishName: 'Georgian', + nativeName: 'ქართული', + }, + kk: { + englishName: 'Kazakh', + nativeName: 'қазақ', + }, + 'lo-LA': { + englishName: 'Lao', + nativeName: 'ລາວ', + }, + oc: { + englishName: 'Occitan', + nativeName: 'Occitan', + }, + 'uz@Cyrl': { + englishName: 'Uzbek (Cyrillic)', + nativeName: 'ўзбек тили', + }, +}; + +export default { updateSettings, isKeepPushingLayoutEnabled, getAvailableLocales, + FALLBACK_LOCALES, }; diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/application/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/application/component.jsx index 5bba7886e8..ff10243a72 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/application/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/application/component.jsx @@ -5,17 +5,12 @@ import LocalesDropdown from '/imports/ui/components/common/locales-dropdown/comp import { defineMessages, injectIntl } from 'react-intl'; import BaseMenu from '../base/component'; import Styled from './styles'; -import VideoService from '/imports/ui/components/video-provider/video-provider-graphql/service'; +import VideoService from '/imports/ui/components/video-provider/service'; import WakeLockService from '/imports/ui/components/wake-lock/service'; import { ACTIONS } from '/imports/ui/components/layout/enums'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; const MIN_FONTSIZE = 0; -const SHOW_AUDIO_FILTERS = (window.meetingClientSettings.public.app - .showAudioFilters === undefined) - ? true - : window.meetingClientSettings.public.app.showAudioFilters; -const { animations } = Settings.application; const intlMessages = defineMessages({ applicationSectionTitle: { @@ -128,6 +123,10 @@ const intlMessages = defineMessages({ autoCloseReactionsBarLabel: { id: 'app.actionsBar.reactions.autoCloseReactionsBarLabel', }, + pushToTalkLabel: { + id: 'app.submenu.application.pushToTalkLabel', + description: 'enable/disable audio push-to-talk', + }, }); class ApplicationMenu extends BaseMenu { @@ -276,6 +275,11 @@ class ApplicationMenu extends BaseMenu { renderAudioFilters() { let audioFilterOption = null; + const SHOW_AUDIO_FILTERS = (window.meetingClientSettings.public.app + .showAudioFilters === undefined) + ? true + : window.meetingClientSettings.public.app.showAudioFilters; + if (SHOW_AUDIO_FILTERS) { const { intl, showToggleLabel, displaySettingsStatus } = this.props; const { settings } = this.state; @@ -311,8 +315,9 @@ class ApplicationMenu extends BaseMenu { } renderPaginationToggle() { - // See VideoService's method for an explanation - if (!VideoService.shouldRenderPaginationToggle()) return false; + const { paginationToggleEnabled } = this.props; + + if (!paginationToggleEnabled) return false; const { intl, showToggleLabel, displaySettingsStatus } = this.props; const { settings } = this.state; @@ -435,6 +440,8 @@ class ApplicationMenu extends BaseMenu { const ariaValueLabel = intl.formatMessage(intlMessages.currentValue, { 0: `${pixelPercentage[settings.fontSize]}` }); const showSelect = allLocales && allLocales.length > 0; + const Settings = getSettingsSingletonInstance(); + const animations = Settings?.application?.animations; return (
@@ -468,6 +475,28 @@ class ApplicationMenu extends BaseMenu { {this.renderAudioFilters()} + + + + + {displaySettingsStatus(settings.pushToTalkEnabled)} + this.handleToggle('pushToTalkEnabled')} + ariaLabel={`${intl.formatMessage(intlMessages.pushToTalkLabel)} - ${displaySettingsStatus(settings.pushToTalkEnabled, true)}`} + showToggleLabel={showToggleLabel} + /> + + + {this.renderPaginationToggle()} {this.renderDarkThemeToggle()} {this.renderWakeLockToggle()} diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/base/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/base/component.jsx index 62be2b14a7..0e621b0ee3 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/base/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/base/component.jsx @@ -15,4 +15,13 @@ export default class BaseMenu extends React.Component { this.handleUpdateSettings(this.state.settingsName, this.state.settings); }); } + + handleInput(key, e) { + const obj = this.state; + obj.settings[key] = e.target.value; + + this.setState(obj, () => { + this.handleUpdateSettings(this.state.settingsName, this.state.settings); + }); + } } diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/notification/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/notification/component.jsx index 7166e6694c..4c2cea2c72 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/notification/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/notification/component.jsx @@ -3,7 +3,6 @@ import Toggle from '/imports/ui/components/common/switch/component'; import { defineMessages, injectIntl } from 'react-intl'; import BaseMenu from '../base/component'; import Styled from './styles'; -import { isChatEnabled } from '/imports/ui/services/features'; const intlMessages = defineMessages({ notificationSectionTitle: { @@ -61,6 +60,7 @@ class NotificationMenu extends BaseMenu { showGuestNotification, showToggleLabel, displaySettingsStatus, + isChatEnabled, } = this.props; const { settings } = this.state; @@ -87,7 +87,7 @@ class NotificationMenu extends BaseMenu { - {isChatEnabled() ? ( + {isChatEnabled ? ( diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/transcription/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/transcription/component.jsx new file mode 100644 index 0000000000..ca1af70cfa --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/transcription/component.jsx @@ -0,0 +1,99 @@ +import React from 'react'; +import Toggle from '/imports/ui/components/common/switch/component'; +import { defineMessages, injectIntl } from 'react-intl'; +import BaseMenu from '../base/component'; +import Styled from './styles'; +import { SETTINGS } from '/imports/ui/services/settings/enums'; + +const intlMessages = defineMessages({ + transcriptionLabel: { + id: 'app.submenu.transcription.sectionTitle', + }, + transcriptionDesc: { + id: 'app.submenu.transcription.desc', + }, + partialUtterancesLabel: { + id: 'app.settings.transcriptionTab.partialUtterances', + }, + minUtteranceLengthLabel: { + id: 'app.settings.transcriptionTab.minUtteranceLength', + }, +}); + +class Transcription extends BaseMenu { + constructor(props) { + super(props); + + this.state = { + settingsName: SETTINGS.TRANSCRIPTION, + settings: props.settings, + }; + } + + render() { + const { intl, showToggleLabel, displaySettingsStatus } = this.props; + + const { partialUtterances, minUtteranceLength } = this.state.settings; + + return ( +
+
+ + {intl.formatMessage(intlMessages.transcriptionLabel)} + + + {intl.formatMessage(intlMessages.transcriptionDesc)} + +
+ + + + + + + {intl.formatMessage(intlMessages.partialUtterancesLabel)} + + + + + + this.handleToggle('partialUtterances')} + ariaLabelledBy="partialUtterances" + ariaLabel={`${intl.formatMessage( + intlMessages.partialUtterancesLabel, + )} - ${displaySettingsStatus(partialUtterances, true)}`} + showToggleLabel={showToggleLabel} + /> + + + + + + + + {intl.formatMessage(intlMessages.minUtteranceLengthLabel)} + + + + + + this.handleInput('minUtteranceLength', e)} + type="number" + max="5" + min="0" + /> + + + + +
+ ); + } +} + +export default injectIntl(Transcription); diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/transcription/styles.js b/bigbluebutton-html5/imports/ui/components/settings/submenus/transcription/styles.js new file mode 100644 index 0000000000..4cf67d4170 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/transcription/styles.js @@ -0,0 +1,29 @@ +import styled from 'styled-components'; +import Styled from '/imports/ui/components/settings/submenus/styles'; + +const Title = styled(Styled.Title)``; + +const SubTitle = styled(Styled.SubTitle)``; + +const Form = styled(Styled.Form)``; + +const Row = styled(Styled.Row)``; + +const Col = styled(Styled.Col)``; + +const FormElement = styled(Styled.FormElement)``; + +const FormElementRight = styled(Styled.FormElementRight)``; + +const Label = styled(Styled.Label)``; + +export default { + Title, + SubTitle, + Form, + Row, + Col, + FormElement, + FormElementRight, + Label, +}; diff --git a/bigbluebutton-html5/imports/ui/components/shortcut-help/component.jsx b/bigbluebutton-html5/imports/ui/components/shortcut-help/component.jsx index 9ae793be39..b0f72b51c1 100644 --- a/bigbluebutton-html5/imports/ui/components/shortcut-help/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/shortcut-help/component.jsx @@ -7,7 +7,7 @@ import ModalSimple from '/imports/ui/components/common/modal/simple/component'; import Styled from './styles'; import StyledSettings from '../settings/styles'; import withShortcutHelper from './service'; -import { isChatEnabled } from '/imports/ui/services/features'; +import { useIsChatEnabled } from '/imports/ui/services/features'; import { uniqueId } from '/imports/utils/string-utils'; const intlMessages = defineMessages({ @@ -246,6 +246,10 @@ const intlMessages = defineMessages({ duplicate: { id: 'app.shortcut-help.duplicate', description: 'describes the duplicate shortcut key', + }, + pushToTalkDesc: { + id: 'app.shortcut-help.pushToTalk', + description: 'describes the push-to-talk shortcut', } }); @@ -269,15 +273,17 @@ const renderItemWhiteBoard = (func, key, alt) => { ); } -const ShortcutHelpComponent = (props) => { - const { intl, shortcuts, - isOpen, - onRequestClose, - priority, - } = props; +const ShortcutHelpComponent = ({ + intl = {}, + shortcuts, + isOpen, + onRequestClose, + priority, +}) => { const { browserName } = browserInfo; const { isIos, isMacos } = deviceInfo; const [ selectedTab, setSelectedTab] = React.useState(0); + const isChatEnabled = useIsChatEnabled(); let accessMod = null; @@ -306,13 +312,19 @@ const ShortcutHelpComponent = (props) => { } const generalShortcutItems = shortcuts.map((shortcut) => { - if (!isChatEnabled() && shortcut.descId.indexOf('Chat') !== -1) return null; + if (!isChatEnabled && shortcut.descId.indexOf('Chat') !== -1) return null; return renderItem( `${intl.formatMessage(intlMessages[`${shortcut.descId.toLowerCase()}`])}`, `${accessMod} + ${shortcut.accesskey}` ); }); + const ptt = renderItem( + `${intl.formatMessage(intlMessages.pushToTalkDesc)}`, + `M` + ); + generalShortcutItems.splice(3, 0, ptt); + const shortcutItems = []; shortcutItems.push(renderItem(intl.formatMessage(intlMessages.togglePan), intl.formatMessage(intlMessages.togglePanKey))); @@ -444,10 +456,6 @@ const ShortcutHelpComponent = (props) => { ); }; -ShortcutHelpComponent.defaultProps = { - intl: {}, -}; - ShortcutHelpComponent.propTypes = { intl: PropTypes.object.isRequired, shortcuts: PropTypes.arrayOf(PropTypes.shape({ diff --git a/bigbluebutton-html5/imports/ui/components/shortcut-help/service.jsx b/bigbluebutton-html5/imports/ui/components/shortcut-help/service.jsx index 3978aaac57..4d74f1ce30 100644 --- a/bigbluebutton-html5/imports/ui/components/shortcut-help/service.jsx +++ b/bigbluebutton-html5/imports/ui/components/shortcut-help/service.jsx @@ -1,9 +1,8 @@ import React from 'react'; import getFromUserSettings from '/imports/ui/services/users-settings'; -const BASE_SHORTCUTS = window.meetingClientSettings.public.app.shortcuts; - const withShortcutHelper = (WrappedComponent, param) => (props) => { + const BASE_SHORTCUTS = window.meetingClientSettings.public.app.shortcuts; const ENABLED_SHORTCUTS = getFromUserSettings('bbb_shortcuts', null); let shortcuts = Object.values(BASE_SHORTCUTS); diff --git a/bigbluebutton-html5/imports/ui/components/sidebar-content/component.jsx b/bigbluebutton-html5/imports/ui/components/sidebar-content/component.jsx index e23e57bc8c..d96c11cf9f 100644 --- a/bigbluebutton-html5/imports/ui/components/sidebar-content/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/sidebar-content/component.jsx @@ -11,6 +11,7 @@ import GuestUsersManagementPanel from '/imports/ui/components/waiting-users/wait import Styled from './styles'; import ErrorBoundary from '/imports/ui/components/common/error-boundary/component'; import FallbackView from '/imports/ui/components/common/fallback-errors/fallback-view/component'; +import GenericContentSidekickContainer from '/imports/ui/components/generic-content/generic-sidekick-content/container'; const propTypes = { top: PropTypes.number.isRequired, @@ -26,16 +27,11 @@ const propTypes = { contextDispatch: PropTypes.func.isRequired, }; -const defaultProps = { - left: null, - right: null, -}; - const SidebarContent = (props) => { const { top, - left, - right, + left = null, + right = null, zIndex, minWidth, width, @@ -157,10 +153,14 @@ const SidebarContent = (props) => { /> )} + {sidebarContentPanel.includes(PANELS.GENERIC_CONTENT_SIDEKICK) && ( + + )} ); }; SidebarContent.propTypes = propTypes; -SidebarContent.defaultProps = defaultProps; export default SidebarContent; diff --git a/bigbluebutton-html5/imports/ui/components/sidebar-content/container.jsx b/bigbluebutton-html5/imports/ui/components/sidebar-content/container.jsx index 05e937cfa3..ba1908d699 100644 --- a/bigbluebutton-html5/imports/ui/components/sidebar-content/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/sidebar-content/container.jsx @@ -1,11 +1,12 @@ import React from 'react'; import SidebarContent from './component'; import { layoutSelectInput, layoutSelectOutput, layoutDispatch } from '../layout/context'; -import { useSubscription } from '@apollo/client'; + import { CURRENT_PRESENTATION_PAGE_SUBSCRIPTION, } from '/imports/ui/components/whiteboard/queries'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; +import useDeduplicatedSubscription from '../../core/hooks/useDeduplicatedSubscription'; const SidebarContentContainer = () => { const sidebarContentInput = layoutSelectInput((i) => i.sidebarContent); @@ -19,7 +20,9 @@ const SidebarContentContainer = () => { const amIPresenter = currentUserData?.presenter; const amIModerator = currentUserData?.isModerator; - const { data: presentationPageData } = useSubscription(CURRENT_PRESENTATION_PAGE_SUBSCRIPTION); + const { data: presentationPageData } = useDeduplicatedSubscription( + CURRENT_PRESENTATION_PAGE_SUBSCRIPTION, + ); const presentationPage = presentationPageData?.pres_page_curr[0] || {}; const currentSlideId = presentationPage?.pageId; diff --git a/bigbluebutton-html5/imports/ui/components/sidebar-navigation/component.jsx b/bigbluebutton-html5/imports/ui/components/sidebar-navigation/component.jsx index 583ed73c6e..76000cd3ab 100644 --- a/bigbluebutton-html5/imports/ui/components/sidebar-navigation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/sidebar-navigation/component.jsx @@ -18,26 +18,19 @@ const propTypes = { contextDispatch: PropTypes.func.isRequired, }; -const defaultProps = { - left: null, - right: null, -}; - -const SidebarNavigation = (props) => { - const { - top, - left, - right, - zIndex, - minWidth, - width, - maxWidth, - height, - isResizable, - resizableEdge, - contextDispatch, - } = props; - +const SidebarNavigation = ({ + top, + left = null, + right = null, + zIndex, + minWidth, + width, + maxWidth, + height, + isResizable, + resizableEdge, + contextDispatch, +}) => { const [resizableWidth, setResizableWidth] = useState(width); const [isResizing, setIsResizing] = useState(false); const [resizeStartWidth, setResizeStartWidth] = useState(0); @@ -106,5 +99,4 @@ const SidebarNavigation = (props) => { }; SidebarNavigation.propTypes = propTypes; -SidebarNavigation.defaultProps = defaultProps; export default SidebarNavigation; diff --git a/bigbluebutton-html5/imports/ui/components/text-input/component.jsx b/bigbluebutton-html5/imports/ui/components/text-input/component.jsx index b05519da1e..f3c4ac1631 100644 --- a/bigbluebutton-html5/imports/ui/components/text-input/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/text-input/component.jsx @@ -6,8 +6,6 @@ import logger from '/imports/startup/client/logger'; import ClickOutside from '/imports/ui/components/click-outside/component'; import Styled from './styles'; -const EMOJI_BUTTON = window.meetingClientSettings.public.app.enableEmojiButton; - const propTypes = { placeholder: PropTypes.string, send: PropTypes.func.isRequired, @@ -97,6 +95,8 @@ class TextInput extends PureComponent { emojiEnabled() { if (isMobile) return false; + const EMOJI_BUTTON = window.meetingClientSettings.public.app.enableEmojiButton; + const { enableEmoji } = this.props; return enableEmoji && EMOJI_BUTTON; } diff --git a/bigbluebutton-html5/imports/ui/components/timer/indicator/component.tsx b/bigbluebutton-html5/imports/ui/components/timer/indicator/component.tsx index 06830b9db3..92d8ae0d29 100644 --- a/bigbluebutton-html5/imports/ui/components/timer/indicator/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/timer/indicator/component.tsx @@ -10,11 +10,6 @@ import { Input } from '../../layout/layoutTypes'; import { TIMER_START, TIMER_STOP } from '../mutations'; import useTimer from '/imports/ui/core/hooks/useTImer'; -const CDN = window.meetingClientSettings.public.app.cdn; -const BASENAME = window.meetingClientSettings.public.app.basename; -const HOST = CDN + BASENAME; -const trackName = window.meetingClientSettings.public.timer.music; - interface TimerIndicatorProps { passedTime: number; stopwatch: boolean; @@ -26,8 +21,6 @@ interface TimerIndicatorProps { startedOn: number; } -type ObjectKey = keyof typeof trackName; - const TimerIndicator: React.FC = ({ passedTime, stopwatch, @@ -49,6 +42,13 @@ const TimerIndicator: React.FC = ({ const [stopTimerMutation] = useMutation(TIMER_STOP); const [songTrackState, setSongTrackState] = useState(songTrack); + const CDN = window.meetingClientSettings.public.app.cdn; + const BASENAME = window.meetingClientSettings.public.app.basename; + const HOST = CDN + BASENAME; + const trackName = window.meetingClientSettings.public.timer.music; + + type ObjectKey = keyof typeof trackName; + const startTimer = () => { startTimerMutation(); }; @@ -77,7 +77,6 @@ const TimerIndicator: React.FC = ({ } return () => { - if (intervalRef.current) clearInterval(intervalRef.current); if (music.current) music.current.pause(); }; }, [songTrack]); @@ -110,6 +109,10 @@ const TimerIndicator: React.FC = ({ } else if (!running) { clearInterval(intervalRef.current); } + + return () => { + if (intervalRef.current) clearInterval(intervalRef.current); + }; }, [running]); useEffect(() => { diff --git a/bigbluebutton-html5/imports/ui/components/timer/panel/component.tsx b/bigbluebutton-html5/imports/ui/components/timer/panel/component.tsx index 080ff54fcd..bbfd09f5e9 100644 --- a/bigbluebutton-html5/imports/ui/components/timer/panel/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/timer/panel/component.tsx @@ -8,7 +8,6 @@ import React, { import { defineMessages, useIntl } from 'react-intl'; import { useMutation, - useSubscription, } from '@apollo/client'; import Header from '/imports/ui/components/common/control-header/component'; import Styled from './styles'; @@ -26,12 +25,12 @@ import { } from '../mutations'; import useTimeSync from '/imports/ui/core/local-states/useTimeSync'; import humanizeSeconds from '/imports/utils/humanizeSeconds'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const MAX_HOURS = 23; const MILLI_IN_HOUR = 3600000; const MILLI_IN_MINUTE = 60000; const MILLI_IN_SECOND = 1000; -const TIMER_CONFIG = window.meetingClientSettings.public.timer; const TRACKS = [ 'noTrack', @@ -114,6 +113,7 @@ const TimerPanel: React.FC = ({ running, timePassed, startedOn, + active, }) => { const [timerReset] = useMutation(TIMER_RESET); const [timerStart] = useMutation(TIMER_START); @@ -241,6 +241,12 @@ const TimerPanel: React.FC = ({ }); }, [timePassed, stopwatch, startedOn]); + useEffect(() => { + if (!active) { + closePanel(); + } + }, [active]); + const timerControls = useMemo(() => { const timeFormatedString = humanizeSeconds(Math.floor(time / 1000)); const timeSplit = timeFormatedString.split(':'); @@ -251,6 +257,8 @@ const TimerPanel: React.FC = ({ const label = running ? intlMessages.stop : intlMessages.start; const color = running ? 'danger' : 'primary'; + const TIMER_CONFIG = window.meetingClientSettings.public.timer; + return (
{ @@ -373,7 +381,7 @@ const TimerPanel: React.FC = ({ return ( {/* @ts-ignore - JS code */}
= ({ }} disabled={stopwatch} color={stopwatch ? 'primary' : 'secondary'} - data-test="stopwatch" + data-test="stopwatchButton" /> = ({ }} disabled={!stopwatch} color={!stopwatch ? 'primary' : 'secondary'} - data-test="timer" + data-test="timerButton" /> {timerControls} @@ -426,7 +434,7 @@ const TimerPanelContaier: React.FC = () => { loading: timerLoading, error: timerError, data: timerData, - } = useSubscription(GET_TIMER); + } = useDeduplicatedSubscription(GET_TIMER); if (timerLoading || !timerData) return null; @@ -456,7 +464,6 @@ const TimerPanelContaier: React.FC = () => { accumulated={timer.accumulated} active={timer.active ?? false} time={timer.time} - endedOn={timer.endedOn} startedOn={timer.startedOn} startedAt={timer.startedAt} /> diff --git a/bigbluebutton-html5/imports/ui/components/user-avatar/component.jsx b/bigbluebutton-html5/imports/ui/components/user-avatar/component.jsx index dd5b91c25e..06fd89e977 100755 --- a/bigbluebutton-html5/imports/ui/components/user-avatar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-avatar/component.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import Styled from './styles'; import browserInfo from '/imports/utils/browserInfo'; @@ -20,87 +20,73 @@ const propTypes = { isSkeleton: PropTypes.bool, }; -const defaultProps = { - children: <>, - moderator: false, - presenter: false, - talking: false, - muted: false, - listenOnly: false, - voice: false, - noVoice: false, - color: '#000', - emoji: false, - avatar: '', - className: '', - isSkeleton: false, -}; - -const { animations } = Settings.application; const { isChrome, isFirefox, isEdge } = browserInfo; const UserAvatar = ({ - children, - moderator, - presenter, - className, - talking, - muted, - listenOnly, - color, - voice, - emoji, - avatar, - noVoice, - whiteboardAccess, - isSkeleton, -}) => ( - <> - {isSkeleton && ({children})} + children = <>, + moderator = false, + presenter = false, + className = '', + talking = false, + muted = false, + listenOnly = false, + color = '#000', + voice = false, + emoji = false, + avatar = '', + noVoice = false, + whiteboardAccess = false, + isSkeleton = false, +}) => { + const Settings = getSettingsSingletonInstance(); + const { animations } = Settings.application; - {!isSkeleton && ( - + )} + + ) +}; UserAvatar.propTypes = propTypes; -UserAvatar.defaultProps = defaultProps; export default UserAvatar; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx index e6783acc37..e48edd661a 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/chat-list-item/component.jsx @@ -9,8 +9,6 @@ import { ACTIONS, PANELS } from '../../layout/enums'; import Icon from '/imports/ui/components/common/icon/component'; const DEBOUNCE_TIME = 1000; -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_id; let globalAppplyStateToProps = () => {}; @@ -49,25 +47,22 @@ const propTypes = { shortcuts: PropTypes.string, }; -const defaultProps = { - shortcuts: '', - tabIndex: -1, -}; - -const ChatListItem = (props) => { - const { - chat, - activeChatId, - idChatOpen, - compact, - intl, - tabIndex, - isPublicChat, - shortcuts: TOGGLE_CHAT_PUB_AK, - sidebarContentIsOpen, - sidebarContentPanel, - layoutContextDispatch, - } = props; +const ChatListItem = ({ + chat, + activeChatId, + idChatOpen, + compact, + intl, + tabIndex = -1, + isPublicChat, + shortcuts = '', + sidebarContentIsOpen, + sidebarContentPanel, + layoutContextDispatch, +}) => { + const TOGGLE_CHAT_PUB_AK = shortcuts; + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_id; const chatPanelOpen = sidebarContentIsOpen && sidebarContentPanel === PANELS.CHAT; @@ -200,6 +195,5 @@ const ChatListItem = (props) => { }; ChatListItem.propTypes = propTypes; -ChatListItem.defaultProps = defaultProps; export default withShortcutHelper(injectIntl(ChatListItem), 'togglePublicChat'); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx index f3468f8372..994ffd68ac 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx @@ -8,12 +8,15 @@ import UserContentContainer from './user-list-content/container'; const propTypes = { compact: PropTypes.bool, CustomLogoUrl: PropTypes.string, + CustomDarkLogoUrl: PropTypes.string, + DarkModeIsEnabled: PropTypes.bool, showBranding: PropTypes.bool.isRequired, }; const defaultProps = { compact: false, CustomLogoUrl: null, + CustomDarkLogoUrl: null, }; class UserList extends PureComponent { @@ -21,16 +24,19 @@ class UserList extends PureComponent { const { compact, CustomLogoUrl, + CustomDarkLogoUrl, + DarkModeIsEnabled, showBranding, } = this.props; + const logoUrl = DarkModeIsEnabled ? CustomDarkLogoUrl : CustomLogoUrl; return ( { showBranding && !compact - && CustomLogoUrl - ? : null + && logoUrl + ? : null } diff --git a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx index da543706da..c8334dd9c2 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx @@ -1,14 +1,23 @@ import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; import getFromUserSettings from '/imports/ui/services/users-settings'; -import Service from '/imports/ui/components/user-list/service'; +import { isDarkThemeEnabled } from '/imports/ui/components/app/service'; import UserList from './component'; +import { useStorageKey } from '../../services/storage/hooks'; -const UserListContainer = (props) => ; +const UserListContainer = (props) => { + const CustomLogoUrl = useStorageKey('CustomLogoUrl', 'session'); + const CustomDarkLogoUrl = useStorageKey('CustomDarkLogoUrl', 'session'); + const DarkModeIsEnabled = isDarkThemeEnabled(); -export default withTracker(({ compact }) => ( - { - CustomLogoUrl: Service.getCustomLogoUrl(), - showBranding: getFromUserSettings('bbb_display_branding_area', window.meetingClientSettings.public.app.branding.displayBrandingArea), - } -))(UserListContainer); + return ( + + ); +}; + +export default UserListContainer; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 9f150171db..c3e5eeb89e 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -1,28 +1,16 @@ import React from 'react'; -import Users from '/imports/api/users'; -import VoiceUsers from '/imports/api/voice-users'; -import Breakouts from '/imports/api/breakouts'; -import Meetings from '/imports/api/meetings'; import Auth from '/imports/ui/services/auth'; import Storage from '/imports/ui/services/storage/session'; -import { EMOJI_STATUSES } from '/imports/utils/statuses'; import KEY_CODES from '/imports/utils/keyCodes'; import AudioService from '/imports/ui/components/audio/service'; -import VideoService from '/imports/ui/components/video-provider/video-provider-graphql/service'; import logger from '/imports/startup/client/logger'; -import { Session } from 'meteor/session'; -import Settings from '/imports/ui/services/settings'; +import Session from '/imports/ui/services/storage/in-memory'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import { notify } from '/imports/ui/services/notification'; import { FormattedMessage } from 'react-intl'; import { getDateString } from '/imports/utils/string-utils'; import { isEmpty } from 'radash'; -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_CHAT_ID = CHAT_CONFIG.public_id; -const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id; -const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; -const USER_STATUS_ENABLED = window.meetingClientSettings.public.userStatus.enabled; - const DIAL_IN_CLIENT_TYPE = 'dial-in-user'; // session for closed chat list @@ -32,12 +20,18 @@ const STARTED_CHAT_LIST_KEY = 'startedChatList'; const CUSTOM_LOGO_URL_KEY = 'CustomLogoUrl'; +const CUSTOM_DARK_LOGO_URL_KEY = 'CustomDarkLogoUrl'; + export const setCustomLogoUrl = (path) => Storage.setItem(CUSTOM_LOGO_URL_KEY, path); +export const setCustomDarkLogoUrl = (path) => Storage.setItem(CUSTOM_DARK_LOGO_URL_KEY, path); + export const setModeratorOnlyMessage = (msg) => Storage.setItem('ModeratorOnlyMessage', msg); const getCustomLogoUrl = () => Storage.getItem(CUSTOM_LOGO_URL_KEY); +const getCustomDarkLogoUrl = () => Storage.getItem(CUSTOM_DARK_LOGO_URL_KEY); + const sortByWhiteboardAccess = (a, b) => { const _a = a.whiteboardAccess; const _b = b.whiteboardAccess; @@ -80,12 +74,13 @@ const sortByPropTime = (propName, propTimeName, nullValue, a, b) => { return 0; }; -const sortUsersByEmoji = (a, b) => sortByPropTime('emoji', 'emojiTime', 'none', a, b); const sortUsersByAway = (a, b) => sortByPropTime('away', 'awayTime', false, a, b); const sortUsersByRaiseHand = (a, b) => sortByPropTime('raiseHand', 'raiseHandTime', false, a, b); const sortUsersByReaction = (a, b) => sortByPropTime('reaction', 'reactionTime', 'none', a, b); const sortUsersByModerator = (a, b) => { + const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; + if (a.role === ROLE_MODERATOR && b.role === ROLE_MODERATOR) { return 0; } if (a.role === ROLE_MODERATOR) { @@ -126,7 +121,6 @@ const sortUsers = (a, b) => { if (sort === 0) sort = sortUsersByRaiseHand(a, b); if (sort === 0) sort = sortUsersByAway(a, b); if (sort === 0) sort = sortUsersByReaction(a, b); - if (sort === 0) sort = sortUsersByEmoji(a, b); if (sort === 0) sort = sortUsersByPhoneUser(a, b); if (sort === 0) sort = sortByWhiteboardAccess(a, b); if (sort === 0) sort = sortUsersByName(a, b); @@ -135,18 +129,15 @@ const sortUsers = (a, b) => { return sort; }; -const isPublicChat = (chat) => ( - chat.userId === PUBLIC_CHAT_ID -); - -const getUserCount = () => Users.find({ meetingId: Auth.meetingID }).count(); - -const hasBreakoutRoom = () => Breakouts.find({ parentMeetingId: Auth.meetingID }, - { fields: {} }).count() > 0; - -const isMe = (userId) => userId === Auth.userID; +const isPublicChat = (chat) => { + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + return chat.userId === CHAT_CONFIG.public_id; +}; const getActiveChats = ({ groupChatsMessages, groupChats, users }) => { + const PUBLIC_GROUP_CHAT_ID = window.meetingClientSettings.public.chat.public_group_id; + const PUBLIC_CHAT_ID = window.meetingClientSettings.public.chat.public_id; + if (isEmpty(groupChats) && isEmpty(users)) return []; const chatIds = Object.keys(groupChats); @@ -192,7 +183,9 @@ const getActiveChats = ({ groupChatsMessages, groupChats, users }) => { const groupChatsParticipants = groupChats[chatId].participants; const otherParticipant = groupChatsParticipants.filter((user) => user.id !== Auth.userID)[0]; const user = users[otherParticipant.id]; - const startedChats = Session.get(STARTED_CHAT_LIST_KEY) || []; + const startedChats = Session.getItem(STARTED_CHAT_LIST_KEY) || []; + + const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; return { color: user?.color || '#7b1fa2', @@ -219,8 +212,11 @@ const getActiveChats = ({ groupChatsMessages, groupChats, users }) => { }); const currentClosedChats = Storage.getItem(CLOSED_CHAT_LIST_KEY) || []; - const removeClosedChats = chatInfo.filter((chat) => !currentClosedChats.find(closedChat => closedChat.chatId === chat.chatId) - && chat.shouldDisplayInChatList); + const removeClosedChats = chatInfo.filter((chat) => { + return !currentClosedChats.some((closedChat) => closedChat.chatId === chat.chatId) + && chat.shouldDisplayInChatList; + }); + const sortByChatIdAndUnread = removeClosedChats.sort((a, b) => { if (a.chatId === PUBLIC_GROUP_CHAT_ID) { return -1; @@ -245,16 +241,10 @@ const getActiveChats = ({ groupChatsMessages, groupChats, users }) => { return sortByChatIdAndUnread; }; -const isVoiceOnlyUser = (userId) => userId.toString().startsWith('v_'); - -const isMeetingLocked = (id) => { - const meeting = Meetings.findOne({ meetingId: id }, - { fields: { lockSettings: 1, usersPolicies: 1 } }); +const isMeetingLocked = (lockSettings, usersPolicies) => { let isLocked = false; - if (meeting.lockSettings !== undefined) { - const { lockSettings, usersPolicies } = meeting; - + if (lockSettings !== undefined) { if (lockSettings.disableCam || lockSettings.disableMic || lockSettings.disablePrivateChat @@ -271,127 +261,6 @@ const isMeetingLocked = (id) => { return isLocked; }; -const getUsersProp = () => { - const meeting = Meetings.findOne( - { meetingId: Auth.meetingID }, - { - fields: { - 'usersPolicies.allowModsToUnmuteUsers': 1, - 'usersPolicies.allowModsToEjectCameras': 1, - 'usersPolicies.authenticatedGuest': 1, - 'usersPolicies.allowPromoteGuestToModerator': 1, - }, - }, - ); - - if (meeting.usersPolicies) return meeting.usersPolicies; - - return { - allowModsToUnmuteUsers: false, - allowModsToEjectCameras: false, - authenticatedGuest: false, - allowPromoteGuestToModerator: false, - }; -}; - -const curatedVoiceUser = (userId) => { - const voiceUser = VoiceUsers.findOne({ userId }); - return { - isVoiceUser: voiceUser ? voiceUser.joined : false, - isMuted: voiceUser ? voiceUser.muted && !voiceUser.listenOnly : false, - isTalking: voiceUser ? voiceUser.talking && !voiceUser.muted : false, - isListenOnly: voiceUser ? voiceUser.listenOnly : false, - }; -}; - -const getAvailableActions = ( - amIModerator, isBreakoutRoom, subjectUser, subjectVoiceUser, usersProp, amIPresenter, -) => { - const isDialInUser = isVoiceOnlyUser(subjectUser.userId) || subjectUser.phone_user; - const amISubjectUser = isMe(subjectUser.userId); - const isSubjectUserModerator = subjectUser.role === ROLE_MODERATOR; - const isSubjectUserGuest = subjectUser.guest; - - const hasAuthority = amIModerator || amISubjectUser; - const allowedToChatPrivately = !amISubjectUser && !isDialInUser; - const allowedToMuteAudio = hasAuthority - && subjectVoiceUser.isVoiceUser - && !subjectVoiceUser.isMuted - && !subjectVoiceUser.isListenOnly; - - const allowedToUnmuteAudio = hasAuthority - && subjectVoiceUser.isVoiceUser - && !subjectVoiceUser.isListenOnly - && subjectVoiceUser.isMuted - && (amISubjectUser || usersProp.allowModsToUnmuteUsers); - - const allowedToResetStatus = hasAuthority - && subjectUser.emoji !== EMOJI_STATUSES.none - && !isDialInUser; - - // if currentUser is a moderator, allow removing other users - const allowedToRemove = amIModerator - && !amISubjectUser - && !isBreakoutRoom; - - const allowedToSetPresenter = amIModerator - && !subjectUser.presenter - && !isDialInUser; - - const allowedToPromote = amIModerator - && !amISubjectUser - && !isSubjectUserModerator - && !isDialInUser - && !isBreakoutRoom - && !(isSubjectUserGuest - && usersProp.authenticatedGuest - && !usersProp.allowPromoteGuestToModerator); - - const allowedToDemote = amIModerator - && !amISubjectUser - && isSubjectUserModerator - && !isDialInUser - && !isBreakoutRoom - && !(isSubjectUserGuest - && usersProp.authenticatedGuest - && !usersProp.allowPromoteGuestToModerator); - - const allowedToChangeStatus = amISubjectUser && USER_STATUS_ENABLED; - - const allowedToChangeUserLockStatus = amIModerator - && !isSubjectUserModerator - && isMeetingLocked(Auth.meetingID); - - const allowedToChangeWhiteboardAccess = amIPresenter - && !amISubjectUser; - - const allowedToEjectCameras = amIModerator - && !amISubjectUser - && usersProp.allowModsToEjectCameras; - - const allowedToSetAway = amISubjectUser && !USER_STATUS_ENABLED; - - return { - allowedToChatPrivately, - allowedToMuteAudio, - allowedToUnmuteAudio, - allowedToResetStatus, - allowedToRemove, - allowedToSetPresenter, - allowedToPromote, - allowedToDemote, - allowedToChangeStatus, - allowedToChangeUserLockStatus, - allowedToChangeWhiteboardAccess, - allowedToEjectCameras, - allowedToSetAway, - }; -}; - -const normalizeEmojiName = (emoji) => ( - emoji in EMOJI_STATUSES ? EMOJI_STATUSES[emoji] : emoji -); - const toggleVoice = (userId, voiceToggle) => { if (userId === Auth.userID) { AudioService.toggleMuteMicrophone(voiceToggle); @@ -404,17 +273,6 @@ const toggleVoice = (userId, voiceToggle) => { } }; -const getEmoji = () => { - const currentUser = Users.findOne({ userId: Auth.userID }, - { fields: { emoji: 1 } }); - - if (!currentUser) { - return false; - } - - return currentUser.emoji; -}; - const focusFirstDropDownItem = () => { const dropdownContent = document.querySelector('div[data-test="dropdownContent"][style="visibility: visible;"]'); if (!dropdownContent) return; @@ -432,13 +290,13 @@ const roving = (...args) => { this.selectedElement = element; const numberOfChilds = elementsList.childElementCount; - const menuOpen = Session.get('dropdownOpen') || false; + const menuOpen = Session.getItem('dropdownOpen') || false; if (menuOpen) { const menuChildren = document.activeElement.getElementsByTagName('li'); if ([KEY_CODES.ESCAPE, KEY_CODES.ARROW_LEFT].includes(event.keyCode)) { - Session.set('dropdownOpen', false); + Session.setItem('dropdownOpen', false); document.activeElement.click(); } @@ -459,7 +317,7 @@ const roving = (...args) => { } if ([KEY_CODES.ESCAPE, KEY_CODES.TAB].includes(event.keyCode)) { - Session.set('dropdownOpen', false); + Session.setItem('dropdownOpen', false); changeState(null); } @@ -500,13 +358,7 @@ const sortUsersByLastName = (a, b) => { return sortUsersByName(aUser, bUser); }; -const isUserPresenter = (userId = Auth.userID) => { - const user = Users.findOne({ userId }, - { fields: { presenter: 1 } }); - return user ? user.presenter : false; -}; - -export const getUserNamesLink = (docTitle, fnSortedLabel, lnSortedLabel, users) => { +export const getUserNamesLink = (docTitle, fnSortedLabel, lnSortedLabel, users, meetingName) => { const mimeType = 'text/plain'; const userNamesObj = users .map((u) => { @@ -533,9 +385,7 @@ export const getUserNamesLink = (docTitle, fnSortedLabel, lnSortedLabel, users) \r\n\r\n${lnSortedLabel}\r\n${namesByLastName}`.replace(/ {2}/g, ' '); const link = document.createElement('a'); - const meeting = Meetings.findOne({ meetingId: Auth.meetingID }, - { fields: { name: 1 } }); - link.setAttribute('download', `bbb-${meeting.name}[users-list]_${getDateString()}.txt`); + link.setAttribute('download', `bbb-${meetingName}[users-list]_${getDateString()}.txt`); link.setAttribute( 'href', `data: ${mimeType};charset=utf-16,${encodeURIComponent(namesListsString)}`, @@ -544,6 +394,7 @@ export const getUserNamesLink = (docTitle, fnSortedLabel, lnSortedLabel, users) }; const UserJoinedMeetingAlert = (obj) => { + const Settings = getSettingsSingletonInstance(); const { userJoinAudioAlerts, userJoinPushAlerts, @@ -553,13 +404,13 @@ const UserJoinedMeetingAlert = (obj) => { if (userJoinAudioAlerts) { AudioService.playAlertSound(`${window.meetingClientSettings.public.app.cdn - + window.meetingClientSettings.public.app.basename - + window.meetingClientSettings.public.app.instanceId}` + + window.meetingClientSettings.public.app.basename}` + '/resources/sounds/userJoin.mp3'); } if (userJoinPushAlerts) { notify( + // eslint-disable-next-line react/jsx-filename-extension { obj.icon, ); } -} +}; const UserLeftMeetingAlert = (obj) => { + const Settings = getSettingsSingletonInstance(); const { userLeaveAudioAlerts, userLeavePushAlerts, @@ -581,8 +433,7 @@ const UserLeftMeetingAlert = (obj) => { if (userLeaveAudioAlerts) { AudioService.playAlertSound(`${window.meetingClientSettings.public.app.cdn - + window.meetingClientSettings.public.app.basename - + window.meetingClientSettings.public.app.instanceId}` + + window.meetingClientSettings.public.app.basename}` + '/resources/sounds/notify.mp3'); } @@ -604,20 +455,12 @@ export default { sortUsers, toggleVoice, getActiveChats, - getAvailableActions, - curatedVoiceUser, - normalizeEmojiName, isMeetingLocked, isPublicChat, roving, getCustomLogoUrl, - hasBreakoutRoom, - getEmojiList: () => EMOJI_STATUSES, - getEmoji, + getCustomDarkLogoUrl, focusFirstDropDownItem, - isUserPresenter, - getUsersProp, - getUserCount, sortUsersByCurrent, UserJoinedMeetingAlert, UserLeftMeetingAlert, diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/breakout-room/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/breakout-room/component.jsx index 1c2203c63f..12791b5c42 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/breakout-room/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/breakout-room/component.jsx @@ -45,6 +45,7 @@ const BreakoutRoomItem = ({ { const sidebarContent = layoutSelectInput((i) => i.sidebarContent); @@ -17,7 +17,7 @@ const BreakoutRoomContainer = ({ breakoutRoom }) => { data: userIsInvitedData, error: userIsInvitedError, loading: userIsInvitedLoading, - } = useSubscription(userIsInvited); + } = useDeduplicatedSubscription(userIsInvited); const { data: currentMeeting, @@ -28,7 +28,7 @@ const BreakoutRoomContainer = ({ breakoutRoom }) => { const { data: currentUser, } = useCurrentUser((u) => ({ - isModerator: u.isModerator, + isModerator: u?.isModerator, })); if (userIsInvitedError) { @@ -60,7 +60,7 @@ const BreakoutRoomContainer = ({ breakoutRoom }) => { layoutContextDispatch, sidebarContentPanel, hasBreakoutRoom: hasBreakoutRoom - && (userIsInvitedData.breakoutRoom.length > 0 || currentUser.isModerator), + && (userIsInvitedData.breakoutRoom.length > 0 || currentUser?.isModerator), breakoutRoom, }} /> diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx index 85c3258df3..aef6124692 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx @@ -8,8 +8,9 @@ import TimerContainer from './timer/container'; import GuestPanelOpenerContainer from '../user-list-graphql/user-participants-title/guest-panel-opener/component'; import UserPollsContainer from './user-polls/container'; import BreakoutRoomContainer from './breakout-room/container'; -import { isChatEnabled } from '/imports/ui/services/features'; import UserTitleContainer from '../user-list-graphql/user-participants-title/component'; +import { GenericSidekickContent } from 'bigbluebutton-html-plugin-sdk'; +import GenericSidekickContentNavButtonContainer from './generic-sidekick-content-button/container'; const propTypes = { currentUser: PropTypes.shape({ @@ -20,7 +21,6 @@ const propTypes = { isTimerActive: PropTypes.bool, }; -const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; const defaultProps = { currentUser: { role: '', @@ -36,18 +36,22 @@ class UserContent extends PureComponent { currentUser, isTimerActive, compact, + isChatEnabled, } = this.props; + const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; + return ( - {isChatEnabled() ? : null} + {isChatEnabled ? : null} {isTimerActive && } {currentUser?.role === ROLE_MODERATOR ? ( - ) : null} + ) : null} + diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx index f4915d1d67..c72c81a768 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx @@ -1,9 +1,10 @@ import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; import UserContent from './component'; -import WaitingUsersService from '/imports/ui/components/waiting-users/service'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; import useMeeting from '/imports/ui/core/hooks/useMeeting'; +import { useIsChatEnabled } from '/imports/ui/services/features'; + +const ASK_MODERATOR = 'ASK_MODERATOR'; const UserContentContainer = (props) => { const { data: currentUser } = useCurrentUser((user) => ({ @@ -18,21 +19,27 @@ const UserContentContainer = (props) => { data: currentMeeting, } = useMeeting((m) => ({ componentsFlags: m.componentsFlags, + usersPolicies: { + guestPolicy: m.usersPolicies.guestPolicy, + }, })); - const { isGuestLobbyMessageEnabled } = WaitingUsersService; + const isChatEnabled = useIsChatEnabled(); + + const APP_SETTINGS = window.meetingClientSettings.public.app; + const isWaitingRoomEnabled = currentMeeting?.usersPolicies?.guestPolicy === ASK_MODERATOR; return ( ); }; -export default withTracker(() => ({ - isWaitingRoomEnabled: WaitingUsersService.isWaitingRoomEnabled(), -}))(UserContentContainer); +export default UserContentContainer; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/component.tsx new file mode 100644 index 0000000000..0c3ac827ee --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/component.tsx @@ -0,0 +1,70 @@ +import React, { useContext } from 'react'; +import { GenericContentType } from 'bigbluebutton-html-plugin-sdk/dist/cjs/extensible-areas/generic-content-item/enums'; +import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; +import Styled from './styles'; +import { PANELS } from '/imports/ui/components/layout/enums'; +import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; +import GenericContentSidekickAreaMenuItem from './menu-item/component'; + +interface GenericComponentSidekickMenuProps { + sidebarContentPanel: string; + layoutContextDispatch: (...args: unknown[]) => void; +} + +interface MappedMenuItems { + [key: string]: PluginSdk.GenericContentSidekickArea[] +} + +const GenericSidekickContentNavButton = ({ + sidebarContentPanel, layoutContextDispatch, +}: GenericComponentSidekickMenuProps) => { + const { pluginsExtensibleAreasAggregatedState } = useContext(PluginsContext); + let genericSidekickContentExtensibleArea = [] as PluginSdk.GenericContentSidekickArea[]; + + if (pluginsExtensibleAreasAggregatedState.genericContentItems) { + const genericMainContent = pluginsExtensibleAreasAggregatedState.genericContentItems + .filter((g) => g.type === GenericContentType.SIDEKICK_AREA) as PluginSdk.GenericContentSidekickArea[]; + genericSidekickContentExtensibleArea = [...genericMainContent]; + } + + const genericContentSidekickId = (id: string) => PANELS.GENERIC_CONTENT_SIDEKICK + id; + + const groupBySidekickMenuSection: MappedMenuItems = {}; + + genericSidekickContentExtensibleArea.forEach((item) => { + const { section } = item; + let alreadySetArray = groupBySidekickMenuSection[section]; + if (alreadySetArray) { + alreadySetArray.push(item); + } else { + alreadySetArray = [item]; + } + groupBySidekickMenuSection[section] = alreadySetArray; + }); + + if (Object.keys(groupBySidekickMenuSection).length !== 0) { + return Object.keys(groupBySidekickMenuSection).map((section) => ( + + + + {section} + + + {groupBySidekickMenuSection[section].map((genericContentSidekickAreaObject) => ( + + ))} + + )); + } + return null; +}; + +export default GenericSidekickContentNavButton; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/container.jsx new file mode 100644 index 0000000000..3d808b55d7 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/container.jsx @@ -0,0 +1,22 @@ +import React from 'react'; +import GenericSidekickContentNavButton from './component'; +import { layoutSelectInput, layoutDispatch } from '/imports/ui/components/layout/context'; + +const GenericSidekickContentNavButtonContainer = (props) => { + const sidebarContent = layoutSelectInput((i) => i.sidebarContent); + const { sidebarContentPanel } = sidebarContent; + const layoutContextDispatch = layoutDispatch(); + + return ( + + ); +}; + +export default GenericSidekickContentNavButtonContainer; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/menu-item/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/menu-item/component.tsx new file mode 100644 index 0000000000..ff4ec05219 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/menu-item/component.tsx @@ -0,0 +1,63 @@ +import * as React from 'react'; +import { useEffect } from 'react'; +import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; +import Icon from '/imports/ui/components/common/icon/component'; +import { ACTIONS, PANELS } from '/imports/ui/components/layout/enums'; +import Styled from '../styles'; + +interface GenericContentSidekickAreaMenuItemProps{ + sidebarContentPanel: string; + genericSidekickContentId: string; + genericContentSidekickAreaObject: PluginSdk.GenericContentSidekickArea; + layoutContextDispatch: (...args: unknown[]) => void; +} + +const GenericContentSidekickAreaMenuItem = ({ + sidebarContentPanel, + genericSidekickContentId, + genericContentSidekickAreaObject, + layoutContextDispatch, +}: GenericContentSidekickAreaMenuItemProps) => { + useEffect(() => { + if (genericContentSidekickAreaObject.open) { + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, + value: true, + }); + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, + value: genericSidekickContentId, + }); + } + }, []); + return ( + + + { + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, + value: sidebarContentPanel !== genericSidekickContentId, + }); + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, + value: sidebarContentPanel === genericSidekickContentId + ? PANELS.NONE + : genericSidekickContentId, + }); + }} + > + + + {genericContentSidekickAreaObject.name} + + + + + ); +}; + +export default GenericContentSidekickAreaMenuItem; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/styles.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/styles.ts new file mode 100644 index 0000000000..78b9df99b3 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/generic-sidekick-content-button/styles.ts @@ -0,0 +1,31 @@ +import styled from 'styled-components'; + +import Styled from '/imports/ui/components/user-list/styles'; +import StyledContent from '/imports/ui/components/user-list/user-list-content/styles'; + +interface ListItemProps { + active: boolean; +} + +const ListItem = styled(StyledContent.ListItem)` + i{ left: 4px; } +`; + +const Section = styled(Styled.Messages)``; + +const Container = styled(StyledContent.Container)``; + +const SmallTitle = styled(Styled.SmallTitle)``; + +const ScrollableList = styled(StyledContent.ScrollableList)``; + +const List = styled(StyledContent.List)``; + +export default { + ListItem, + Section, + Container, + SmallTitle, + ScrollableList, + List, +}; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/styles.js b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/styles.js index 8deb290dd0..8366163d19 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/styles.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/styles.js @@ -17,9 +17,8 @@ import { colorGrayDark, colorGrayLight, colorGrayLighter, - listItemBgHover, - itemFocusBorder, unreadMessagesBg, + colorGrayLightest, } from '/imports/ui/stylesheets/styled-components/palette'; import { fontSizeSmall } from '/imports/ui/stylesheets/styled-components/typography'; import { ScrollboxVertical } from '/imports/ui/stylesheets/styled-components/scrollable'; @@ -129,10 +128,12 @@ const ListItem = styled(Styled.ListItem)` text-overflow: ellipsis; } - &:active { - background-color: ${listItemBgHover}; - box-shadow: inset 0 0 0 ${borderSize} ${itemFocusBorder}, inset 1px 0 0 1px ${itemFocusBorder}; - } + ${({ active }) => active && ` + outline: transparent; + outline-style: dotted; + outline-width: ${borderSize}; + background-color: ${colorGrayLightest}; +`} `; const UnreadMessages = styled(FlexColumn)` diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/timer/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/timer/component.jsx index 31e2e6f6b4..41b03910a6 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/timer/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/timer/component.jsx @@ -56,6 +56,7 @@ class Timer extends PureComponent { { layoutContextDispatch({ type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/chat-list-item/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/chat-list-item/component.tsx index 0995cce9c5..968b91f67b 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/chat-list-item/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/chat-list-item/component.tsx @@ -27,15 +27,8 @@ const intlMessages = defineMessages({ interface ChatListItemProps { chat: Chat, + chatNodeRef: React.Ref, } -// @ts-ignore - temporary, while meteor exists in the project -const CHAT_CONFIG = window.meetingClientSettings.public.chat; -// @ts-ignore - temporary, while meteor exists in the project -const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; - -const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id; - -const isPublicGroupChat = (chat: Chat) => chat.chatId === PUBLIC_GROUP_CHAT_ID; const ChatListItem = (props: ChatListItemProps) => { const sidebarContent = layoutSelectInput((i: Input) => i.sidebarContent); @@ -48,6 +41,7 @@ const ChatListItem = (props: ChatListItemProps) => { const TOGGLE_CHAT_PUB_AK: string = useShortcut('togglePublicChat'); const { chat, + chatNodeRef, } = props; const countUnreadMessages = chat.totalUnread || 0; @@ -58,6 +52,13 @@ const ChatListItem = (props: ChatListItemProps) => { const isCurrentChat = chat.chatId === idChatOpen && chatPanelOpen; + const ROLE_MODERATOR = window.meetingClientSettings.public.user.role_moderator; + + const CHAT_CONFIG = window.meetingClientSettings.public.chat; + const PUBLIC_GROUP_CHAT_ID = CHAT_CONFIG.public_group_id; + + const isPublicGroupChat = (chat: Chat) => chat.chatId === PUBLIC_GROUP_CHAT_ID; + useEffect(() => { if (chat.chatId !== PUBLIC_GROUP_CHAT_ID && chat.chatId === idChatOpen) { layoutContextDispatch({ @@ -86,9 +87,27 @@ const ChatListItem = (props: ChatListItemProps) => { }); } else { layoutContextDispatch({ - type: ACTIONS.SET_ID_CHAT_OPEN, - value: chat.chatId, + type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, + value: PANELS.NONE, }); + layoutContextDispatch({ + type: ACTIONS.SET_ID_CHAT_OPEN, + value: '', + }); + setTimeout(() => { + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN, + value: true, + }); + layoutContextDispatch({ + type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL, + value: PANELS.CHAT, + }); + layoutContextDispatch({ + type: ACTIONS.SET_ID_CHAT_OPEN, + value: chat.chatId, + }); + }, 0); } } else { layoutContextDispatch({ @@ -132,6 +151,7 @@ const ChatListItem = (props: ChatListItemProps) => { e.stopPropagation(); } }} + ref={chatNodeRef} > diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/chat-list-item/styles.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/chat-list-item/styles.ts index 68d98f28fb..f2f9573c5a 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/chat-list-item/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/chat-list-item/styles.ts @@ -16,6 +16,7 @@ import { colorSuccess, itemFocusBorder, unreadMessagesBg, + colorGrayLightest, } from '/imports/ui/stylesheets/styled-components/palette'; interface UserAvatarProps { @@ -31,6 +32,7 @@ interface ChatNameMainProps { interface ChatListItemProps { active: boolean; + ref: React.Ref; } const ChatListItemLink = styled.div` @@ -184,7 +186,6 @@ const ChatListItem = styled.button` background-color: ${listItemBgHover}; } - &:active, &:focus { outline: transparent; outline-width: ${borderSize}; @@ -213,6 +214,12 @@ const ChatListItem = styled.button` margin-left: 0; margin-right: ${borderSize}; } + ${({ active }: ChatListItemProps) => active && ` + outline: transparent; + outline-style: dotted; + outline-width: ${borderSize}; + background-color: ${colorGrayLightest}; + `} `; const ChatThumbnail = styled.div` diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/component.tsx index 5feb17e905..78b99fe43c 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/chat-list/component.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { TransitionGroup, CSSTransition } from 'react-transition-group'; import { defineMessages, useIntl } from 'react-intl'; -import { findDOMNode } from 'react-dom'; import Styled from './styles'; import ChatListItem from './chat-list-item/component'; import useChat from '/imports/ui/core/hooks/useChat'; @@ -20,7 +19,7 @@ interface ChatListProps { chats: Chat[], } -const getActiveChats = (chats: Chat[]) => chats.map((chat) => ( +const getActiveChats = (chats: Chat[], chatNodeRef: React.Ref) => chats.map((chat) => ( chats.map((chat) => ( timeout={0} component="div" key={chat.chatId} + nodeRef={chatNodeRef} > @@ -43,6 +44,7 @@ const ChatList: React.FC = ({ chats }) => { const messageItemsRef = React.useRef(null); const [selectedChat, setSelectedChat] = React.useState(); const { roving } = Service; + const chatNodeRef = React.useRef(null); React.useEffect(() => { const firstChild = (selectedChat as HTMLElement)?.firstChild; @@ -50,8 +52,7 @@ const ChatList: React.FC = ({ chats }) => { }, [selectedChat]); const rove = (event: React.KeyboardEvent) => { - // eslint-disable-next-line react/no-find-dom-node - const msgItemsRef = findDOMNode(messageItemsRef.current); + const msgItemsRef = messageItemsRef.current; const msgItemsRefChild = msgItemsRef?.firstChild; roving(event, setSelectedChat, msgItemsRefChild, selectedChat); event.stopPropagation(); @@ -73,7 +74,7 @@ const ChatList: React.FC = ({ chats }) => { > - {getActiveChats(chats) ?? null} + {getActiveChats(chats, chatNodeRef) ?? null} diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/component.tsx index 5ced430ea4..3546d43cd6 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/component.tsx @@ -1,108 +1,35 @@ import React, { useEffect } from 'react'; -import { useSubscription } from '@apollo/client'; -import { AutoSizer } from 'react-virtualized'; -import { debounce } from 'radash'; -import { ListProps } from 'react-virtualized/dist/es/List'; + import { findDOMNode } from 'react-dom'; import { UI_DATA_LISTENER_SUBSCRIBED } from 'bigbluebutton-html-plugin-sdk/dist/cjs/ui-data-hooks/consts'; import { UserListUiDataPayloads } from 'bigbluebutton-html-plugin-sdk/dist/cjs/ui-data-hooks/user-list/types'; import * as PluginSdk from 'bigbluebutton-html-plugin-sdk'; +import { User } from '/imports/ui/Types/user'; import Styled from './styles'; -import ListItem from './list-item/component'; -import Skeleton from './list-item/skeleton/component'; -import UserActions from './user-actions/component'; import { - MEETING_PERMISSIONS_SUBSCRIPTION, USER_AGGREGATE_COUNT_SUBSCRIPTION, } from './queries'; -import { User } from '/imports/ui/Types/user'; -import { Meeting } from '/imports/ui/Types/meeting'; -import { - CURRENT_PRESENTATION_PAGE_SUBSCRIPTION, -} from '/imports/ui/components/whiteboard/queries'; -import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; -import { layoutSelect } from '/imports/ui/components/layout/context'; -import { Layout } from '/imports/ui/components/layout/layoutTypes'; import Service from '/imports/ui/components/user-list/service'; -import { setLocalUserList, useLoadedUserList } from '/imports/ui/core/hooks/useLoadedUserList'; -import { GraphqlDataHookSubscriptionResponse } from '/imports/ui/Types/hook'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; +import UserListParticipantsPageContainer from './page/component'; +import IntersectionWatcher from './intersection-watcher/intersectionWatcher'; +import { setLocalUserList } from '/imports/ui/core/hooks/useLoadedUserList'; interface UserListParticipantsProps { - users: Array; - offset: number; - setOffset: (offset: number) => void; - setLimit: (limit: number) => void, - meeting: Meeting; - currentUser: Partial; count: number; - pageId: string; } -interface RowRendererProps extends ListProps { - users: Array; - validCurrentUser: Partial; - meeting: Meeting; - offset: number; - index: number; - openUserAction: string | null; - setOpenUserAction: React.Dispatch>; -} -const rowRenderer: React.FC = ({ - index, key, style, users, validCurrentUser, offset, meeting, isRTL, pageId, openUserAction, setOpenUserAction, -}) => { - const userIndex = index - offset; - const user = users && users[userIndex]; - const direction = isRTL ? 'rtl' : 'ltr'; - - return ( -
- {user && validCurrentUser && meeting ? ( - - - - ) : ( - - )} -
- ); -}; const UserListParticipants: React.FC = ({ - users, - setOffset, - setLimit, - offset, - currentUser, - meeting, count, - pageId, }) => { - const validCurrentUser: Partial = currentUser && currentUser.userId - ? currentUser - : { userId: '', isModerator: false, presenter: false }; - + const [visibleUsers, setVisibleUsers] = React.useState<{ + [key: number]: User[]; + }>({}); const userListRef = React.useRef(null); const userItemsRef = React.useRef(null); const [selectedUser, setSelectedUser] = React.useState(); - const [openUserAction, setOpenUserAction] = React.useState(null); const { roving } = Service; - const isRTL = layoutSelect((i: Layout) => i.isRTL); - const [previousUsersData, setPreviousUsersData] = React.useState(users); - useEffect(() => { - if (users?.length) { - setPreviousUsersData(users); - } - }, [users]); - React.useEffect(() => { const firstChild = (selectedUser as HTMLElement)?.firstChild; @@ -110,6 +37,22 @@ const UserListParticipants: React.FC = ({ if (fourthChild && fourthChild instanceof HTMLElement) fourthChild.focus(); }, [selectedUser]); + useEffect(() => { + const keys = Object.keys(visibleUsers); + if (keys.length > 0) { + // eslint-disable-next-line + const visibleUserArr = keys.sort().reduce((acc, key) => { + return [ + ...acc, + // @ts-ignore + ...visibleUsers[key], + ]; + }, [] as User[]); + // eslint-disable-next-line + setLocalUserList(visibleUserArr); + } + }, [visibleUsers]); + // --- Plugin related code --- useEffect(() => { const updateUiDataHookCurrentVolumeForPlugin = () => { @@ -152,91 +95,59 @@ const UserListParticipants: React.FC = ({ event.stopPropagation(); }; - + const amountOfPages = Math.ceil(count / 50); return ( - - - {({ width, height }) => ( - rowRenderer( - { - ...props, - users: users || previousUsersData, - validCurrentUser, - offset, - meeting, - isRTL, - pageId, - openUserAction, - setOpenUserAction, - }, + + + { + Array.from({ length: amountOfPages }).map((_, i) => { + const isLastItem = amountOfPages === (i + 1); + const restOfUsers = count % 50; + const key = i; + return i === 0 + ? ( + ) - } - ref={userItemsRef} - noRowRenderer={() =>
no users
} - rowCount={count} - height={height - 1} - width={width - 1} - onRowsRendered={debounce({ delay: 500 }, ({ overscanStartIndex, overscanStopIndex }) => { - setOffset(overscanStartIndex); - const limit = (overscanStopIndex - overscanStartIndex) + 1; - setLimit(limit < 50 ? 50 : limit); - })} - overscanRowCount={10} - rowHeight={50} - /> - )} -
+ : ( + + + + ); + }) + } +
); }; const UserListParticipantsContainer: React.FC = () => { - const [offset, setOffset] = React.useState(0); - const [limit, setLimit] = React.useState(50); - - const { - data: meetingData, - } = useSubscription(MEETING_PERMISSIONS_SUBSCRIPTION); - const { meeting: meetingArray } = (meetingData || {}); - const meeting = meetingArray && meetingArray[0]; const { data: countData, - } = useSubscription(USER_AGGREGATE_COUNT_SUBSCRIPTION); + } = useDeduplicatedSubscription(USER_AGGREGATE_COUNT_SUBSCRIPTION); const count = countData?.user_aggregate?.aggregate?.count || 0; - useEffect(() => () => { - setLocalUserList([]); - }, []); - - const { - data: usersData, - } = useLoadedUserList({ offset, limit }, (u) => u) as GraphqlDataHookSubscriptionResponse>; - const users = usersData ?? []; - - const { data: currentUser } = useCurrentUser((c: Partial) => ({ - isModerator: c.isModerator, - userId: c.userId, - presenter: c.presenter, - })); - - const { data: presentationData } = useSubscription(CURRENT_PRESENTATION_PAGE_SUBSCRIPTION); - const presentationPage = presentationData?.pres_page_curr[0] || {}; - const pageId = presentationPage?.pageId; - - setLocalUserList(users); return ( <> ); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/intersection-watcher/intersectionWatcher.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/intersection-watcher/intersectionWatcher.tsx new file mode 100644 index 0000000000..280147ce7a --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/intersection-watcher/intersectionWatcher.tsx @@ -0,0 +1,63 @@ +import React, { useEffect } from 'react'; +import useIntersectionObserver from '/imports/ui/hooks/useIntersectionObserver'; +import SkeletonUserListItem from '../list-item/skeleton/component'; + +const MOUNT_DELAY = 1000; + +const UNMOUNT_DELAY = 20000; + +interface IntersectionWatcherProps { + ParentRef: React.MutableRefObject; + children: React.ReactNode; + isLastItem: boolean; + restOfUsers: number; +} + +const IntersectionWatcher: React.FC = ({ + children, + ParentRef, + isLastItem, + restOfUsers, +}) => { + const childrenRef = React.useRef(null); + const setTimoutRef = React.useRef>(); + const [renderPage, setRenderPage] = React.useState(false); + const { + childRefProxy, + intersecting, + } = useIntersectionObserver(ParentRef, childrenRef, 0); + + const handleIntersection = (bool: boolean) => { + clearTimeout(setTimoutRef.current); + if (bool) { + setTimoutRef.current = setTimeout(() => { + setRenderPage(true); + }, MOUNT_DELAY); + } else { + setTimoutRef.current = setTimeout(() => { + setRenderPage(false); + }, UNMOUNT_DELAY); + } + }; + + useEffect(() => { + if (intersecting) { + handleIntersection(true); + } else { + handleIntersection(false); + } + }, [intersecting]); + + return ( +
+ { + renderPage ? children + : Array.from({ length: isLastItem ? restOfUsers : 50 }).map((_, index) => ( + + )) + } +
+ ); +}; + +export default IntersectionWatcher; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/component.tsx index ad635d6314..73689a3824 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/component.tsx @@ -13,10 +13,11 @@ import TooltipContainer from '/imports/ui/components/common/tooltip/container'; import Auth from '/imports/ui/services/auth'; import { LockSettings } from '/imports/ui/Types/meeting'; import { uniqueId } from '/imports/utils/string-utils'; -import normalizeEmojiName from './service'; import { convertRemToPixels } from '/imports/utils/dom-utils'; import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context'; -import { isReactionsEnabled } from '/imports/ui/services/features'; +import { useIsReactionsEnabled } from '/imports/ui/services/features'; +import useWhoIsTalking from '/imports/ui/core/hooks/useWhoIsTalking'; +import useWhoIsUnmuted from '/imports/ui/core/hooks/useWhoIsUnmuted'; const messages = defineMessages({ moderator: { @@ -49,9 +50,6 @@ const messages = defineMessages({ }, }); -// @ts-ignore - temporary, while meteor exists in the project -const LABEL = window.meetingClientSettings.public.user.label; - const { isChrome, isFirefox, isEdge } = browserInfo; interface EmojiProps { @@ -103,9 +101,17 @@ const UserListItem: React.FC = ({ user, lockSettings }) => { } const intl = useIntl(); - const voiceUser = user.voice; + const { data: talkingUsers } = useWhoIsTalking(); + const { data: unmutedUsers } = useWhoIsUnmuted(); + const voiceUser = { + ...user.voice, + talking: talkingUsers[user.userId], + muted: !unmutedUsers[user.userId], + }; const subs = []; + const LABEL = window.meetingClientSettings.public.user.label; + if (user.isModerator && LABEL.moderator) { subs.push(intl.formatMessage(messages.moderator)); } @@ -153,15 +159,15 @@ const UserListItem: React.FC = ({ user, lockSettings }) => { subs.push( { itemToRender.icon - && } + && } {itemToRender.label} , ); }); - const reactionsEnabled = isReactionsEnabled(); + const reactionsEnabled = useIsReactionsEnabled(); - const userAvatarFiltered = (user.raiseHand === true || user.away === true || (user.reaction && user.reaction.reactionEmoji !== 'none')) ? '' : user.avatar; + const userAvatarFiltered = (user.raiseHand === true || user.away === true || (user.reactionEmoji && user.reactionEmoji !== 'none')) ? '' : user.avatar; const emojiIcons = [ { @@ -183,18 +189,15 @@ const UserListItem: React.FC = ({ user, lockSettings }) => { if (user.raiseHand === true) { return reactionsEnabled ? - : ; + : ; } if (user.away === true) { return reactionsEnabled ? - : ; + : ; } - if (user.emoji !== 'none' && user.emoji !== 'notAway') { - return ; - } - if (user.reaction && user.reaction.reactionEmoji !== 'none') { - return user.reaction.reactionEmoji; + if (user.reactionEmoji && user.reactionEmoji !== 'none') { + return user.reactionEmoji; } if (user.name && userAvatarFiltered.length === 0) { return user.name.toLowerCase().slice(0, 2); @@ -236,7 +239,6 @@ const UserListItem: React.FC = ({ user, lockSettings }) => { color={user.color} whiteboardAccess={hasWhiteboardAccess} animations - emoji={user.emoji !== 'none'} avatar={userAvatarFiltered} isChrome={isChrome} isFirefox={isFirefox} diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/service.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/service.ts deleted file mode 100644 index 3c5122df78..0000000000 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/service.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { EMOJI_STATUSES } from '/imports/utils/statuses'; - -const normalizeEmojiName = (emoji: string) => { - const statusAvailable = (Object.keys(EMOJI_STATUSES).includes(emoji)); - - return statusAvailable ? (EMOJI_STATUSES as Record)[emoji] : emoji; -}; - -export default normalizeEmojiName; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/skeleton/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/skeleton/component.tsx index f0fb77f5a7..981d944d15 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/skeleton/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/skeleton/component.tsx @@ -2,16 +2,23 @@ import React from 'react'; import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; import Styled from './styles'; import listItemStyles from '../styles'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; -const SkeletonUserListItem: React.FC = () => { +interface SkeletonUserListItemProps { + enableAnimation?: boolean; +} + +const SkeletonUserListItem: React.FC = ({ + enableAnimation = true, +}) => { + const Settings = getSettingsSingletonInstance(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - temporary while settings are still in .js const { isRTL } = Settings.application; return ( - +
diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/styles.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/styles.ts index 037b12d9b4..9e7dedf4f8 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/list-item/styles.ts @@ -22,6 +22,8 @@ import { colorOffWhite, } from '/imports/ui/stylesheets/styled-components/palette'; +import Icon from '/imports/ui/components/common/icon/icon-ts/component'; + interface AvatarProps { moderator?: boolean; presenter?: boolean; @@ -190,6 +192,7 @@ const Avatar = styled.div` ${({ moderator }) => moderator && ` border-radius: 5px; + color: ${colorWhite} !important; `} ${({ presenter }) => presenter && ` @@ -322,7 +325,7 @@ const Avatar = styled.div` // ================ image ================ // ================ content ================ - color: ${colorWhite}; + color: ${colorWhite} !important; font-size: 110%; text-transform: capitalize; display: flex; @@ -340,6 +343,10 @@ const Skeleton = styled.div` `; +const UserAdditionalInformationIcon = styled(Icon)` + margin-right: ${smPaddingX}; +`; + const pulse = (color: string) => keyframes` 0% { box-shadow: 0 0 0 0 ${color}80; @@ -413,6 +420,7 @@ export default { Skeleton, UserItemContents, UserNameContainer, + UserAdditionalInformationIcon, UserNameSub, UserName, IconRightContainer, diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/page/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/page/component.tsx new file mode 100644 index 0000000000..c74c0600ad --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/page/component.tsx @@ -0,0 +1,141 @@ +import React, { useEffect, useRef } from 'react'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; +import { MEETING_PERMISSIONS_SUBSCRIPTION } from '../queries'; +import { setLocalUserList, useLoadedUserList } from '/imports/ui/core/hooks/useLoadedUserList'; +import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; +import { CURRENT_PRESENTATION_PAGE_SUBSCRIPTION } from '/imports/ui/components/whiteboard/queries'; +import { User } from '/imports/ui/Types/user'; +import { GraphqlDataHookSubscriptionResponse } from '/imports/ui/Types/hook'; +import { Meeting } from '/imports/ui/Types/meeting'; +import Styled from '../styles'; +import UserActions from '../user-actions/component'; +import ListItem from '../list-item/component'; +import { layoutSelect } from '/imports/ui/components/layout/context'; +import { Layout } from '/imports/ui/components/layout/layoutTypes'; +import SkeletonUserListItem from '../list-item/skeleton/component'; + +interface UserListParticipantsContainerProps { + index: number; + isLastItem: boolean; + restOfUsers: number; + setVisibleUsers: React.Dispatch>; +} + +interface UsersListParticipantsPage { + users: Array; + meeting: Meeting; + currentUser: Partial; + pageId: string; +} + +const UsersListParticipantsPage: React.FC = ({ + users, + currentUser, + meeting, + pageId, +}) => { + const [openUserAction, setOpenUserAction] = React.useState(null); + const isRTL = layoutSelect((i: Layout) => i.isRTL); + return ( + <> + { + users.map((user) => { + return ( + + + + + + ); + }) + } + + ); +}; + +const UserListParticipantsPageContainer: React.FC = ({ + index, + isLastItem, + restOfUsers, + setVisibleUsers, +}) => { + const offset = index * 50; + const limit = useRef(50); + + const { + data: meetingData, + loading: meetingLoading, + } = useDeduplicatedSubscription(MEETING_PERMISSIONS_SUBSCRIPTION); + const { meeting: meetingArray } = (meetingData || {}); + const meeting = meetingArray && meetingArray[0]; + + useEffect(() => () => { + setLocalUserList([]); + }, []); + + const { + data: usersData, + loading: usersLoading, + } = useLoadedUserList({ offset, limit: limit.current }, (u) => u) as GraphqlDataHookSubscriptionResponse>; + const users = usersData ?? []; + + const { data: currentUser, loading: currentUserLoading } = useCurrentUser((c: Partial) => ({ + isModerator: c.isModerator, + userId: c.userId, + presenter: c.presenter, + })); + + const { + data: presentationData, + loading: presentationLoading, + } = useDeduplicatedSubscription(CURRENT_PRESENTATION_PAGE_SUBSCRIPTION); + const presentationPage = presentationData?.pres_page_curr[0] || {}; + const pageId = presentationPage?.pageId; + + useEffect(() => { + setVisibleUsers((prev) => { + const newList = { ...prev }; + newList[index] = users; + return newList; + }); + }, [usersData]); + + useEffect(() => { + return () => { + setVisibleUsers((prev) => { + // eslint-disable-next-line + prev[index] = []; + return prev; + }); + }; + }, []); + + if (usersLoading || meetingLoading || currentUserLoading || presentationLoading) { + return Array.from({ length: isLastItem ? restOfUsers : 50 }).map((_, i) => ( + + {/* eslint-disable-next-line */} + + + )); + } + + return ( + + ); +}; + +export default UserListParticipantsPageContainer; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/styles.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/styles.ts index e237534a85..de5e29738b 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/styles.ts @@ -14,7 +14,7 @@ import { } from '/imports/ui/stylesheets/styled-components/palette'; import { - VirtualizedScrollboxVertical, + ScrollboxVertical, } from '/imports/ui/stylesheets/styled-components/scrollable'; interface AvatarProps { @@ -259,7 +259,7 @@ const pulse = (color: string) => keyframes` } `; -const VirtualizedList = styled(VirtualizedScrollboxVertical)` +const VirtualizedList = styled(ScrollboxVertical)` background: linear-gradient(#f3f6f9 30%, rgba(255,255,255,0)), linear-gradient(rgba(255,255,255,0), #f3f6f9 70%) 0 100%, /* Shadows */ @@ -267,6 +267,11 @@ const VirtualizedList = styled(VirtualizedScrollboxVertical)` radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%; outline: none; + overflow-x: hidden; +`; + +const UserListItem = styled.div` + padding: .25em 0; `; export default { @@ -274,4 +279,5 @@ export default { Skeleton, UserListColumn, VirtualizedList, + UserListItem, }; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx index 2170e83ae5..3c5da63586 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/component.tsx @@ -15,7 +15,6 @@ import { EJECT_FROM_MEETING, EJECT_FROM_VOICE, SET_PRESENTER, - SET_EMOJI_STATUS, SET_LOCKED, } from '/imports/ui/core/graphql/mutations/userMutations'; import { @@ -26,10 +25,9 @@ import { isVoiceOnlyUser, } from './service'; -import { isChatEnabled } from '/imports/ui/services/features'; +import { useIsChatEnabled } from '/imports/ui/services/features'; import { layoutDispatch } from '/imports/ui/components/layout/context'; import { PANELS, ACTIONS } from '/imports/ui/components/layout/enums'; -import { EMOJI_STATUSES } from '/imports/utils/statuses'; import ConfirmationModal from '/imports/ui/components/common/modal/confirmation/component'; @@ -41,6 +39,7 @@ import { useMutation, useLazyQuery } from '@apollo/client'; import { CURRENT_PAGE_WRITERS_QUERY } from '/imports/ui/components/whiteboard/queries'; import { PRESENTATION_SET_WRITERS } from '/imports/ui/components/presentation/mutations'; import useToggleVoice from '/imports/ui/components/audio/audio-graphql/hooks/useToggleVoice'; +import useWhoIsUnmuted from '/imports/ui/core/hooks/useWhoIsUnmuted'; interface UserActionsProps { user: User; @@ -72,10 +71,6 @@ interface Writer { } const messages = defineMessages({ - statusTriggerLabel: { - id: 'app.actionsBar.emojiMenu.statusTriggerLabel', - description: 'label for option to show emoji menu', - }, UnpinUserWebcam: { id: 'app.userList.menu.webcamUnpin.label', description: 'label for pin user webcam', @@ -88,10 +83,6 @@ const messages = defineMessages({ id: 'app.userList.menu.chat.label', description: 'label for option to start a new private chat', }, - ClearStatusLabel: { - id: 'app.userList.menu.clearStatus.label', - description: 'Clear the emoji status of this user', - }, MuteUserAudioLabel: { id: 'app.userList.menu.muteUserAudio.label', description: 'Forcefully mute this user', @@ -144,10 +135,6 @@ const messages = defineMessages({ id: 'app.userList.menu.ejectUserCameras.label', description: 'label to eject user cameras', }, - backTriggerLabel: { - id: 'app.audio.backLabel', - description: 'label for option to hide emoji menu', - }, }); const makeDropdownPluginItem: ( userDropdownItems: PluginSdk.UserListDropdownInterface[]) => DropdownItem[] = ( @@ -208,13 +195,19 @@ const UserActions: React.FC = ({ setOpenUserAction, }) => { const intl = useIntl(); - const [showNestedOptions, setShowNestedOptions] = useState(false); const [isConfirmationModalOpen, setIsConfirmationModalOpen] = useState(false); const layoutContextDispatch = layoutDispatch(); const [presentationSetWriters] = useMutation(PRESENTATION_SET_WRITERS); - const [getWriters] = useLazyQuery(CURRENT_PAGE_WRITERS_QUERY, { fetchPolicy: 'no-cache' }); + const [getWriters] = useLazyQuery( + CURRENT_PAGE_WRITERS_QUERY, + { + variables: { pageId }, + fetchPolicy: 'no-cache', + }, + ); const voiceToggle = useToggleVoice(); + const isChatEnabled = useIsChatEnabled(); const handleWhiteboardAccessChange = async () => { try { @@ -250,17 +243,20 @@ const UserActions: React.FC = ({ }; const { pluginsExtensibleAreasAggregatedState } = useContext(PluginsContext); + + const { data: unmutedUsers } = useWhoIsUnmuted(); + const isMuted = !unmutedUsers[user.userId]; + const actionsnPermitions = generateActionsPermissions( user, currentUser, lockSettings, usersPolicies, isBreakout, + isMuted, ); const { - allowedToChangeStatus, allowedToChatPrivately, - allowedToResetStatus, allowedToMuteAudio, allowedToUnmuteAudio, allowedToChangeWhiteboardAccess, @@ -297,7 +293,6 @@ const UserActions: React.FC = ({ const [ejectFromMeeting] = useMutation(EJECT_FROM_MEETING); const [ejectFromVoice] = useMutation(EJECT_FROM_VOICE); const [setPresenter] = useMutation(SET_PRESENTER); - const [setEmojiStatus] = useMutation(SET_EMOJI_STATUS); const [setLocked] = useMutation(SET_LOCKED); const [userEjectCameras] = useMutation(USER_EJECT_CAMERAS); @@ -323,15 +318,6 @@ const UserActions: React.FC = ({ ...makeDropdownPluginItem(userDropdownItems.filter( (item: PluginSdk.UserListDropdownInterface) => (item?.type === UserListDropdownItemType.INFORMATION), )), - { - allowed: allowedToChangeStatus, - key: 'setstatus', - label: intl.formatMessage(messages.statusTriggerLabel), - onClick: () => setShowNestedOptions(true), - icon: 'user', - iconRight: 'right_arrow', - dataTest: 'setStatus', - }, { allowed: user.cameras.length > 0 && isVideoPinEnabledForCurrentUser(currentUser, isBreakout), @@ -351,7 +337,7 @@ const UserActions: React.FC = ({ icon: user.pinned ? 'pin-video_off' : 'pin-video_on', }, { - allowed: isChatEnabled() + allowed: isChatEnabled && ( currentUser.isModerator ? allowedToChatPrivately : allowedToChatPrivately && ( @@ -388,28 +374,13 @@ const UserActions: React.FC = ({ icon: 'chat', dataTest: 'startPrivateChat', }, - { - allowed: allowedToResetStatus - && user.emoji !== 'none', - key: 'clearStatus', - label: intl.formatMessage(messages.ClearStatusLabel), - onClick: () => { - setEmojiStatus({ - variables: { - emoji: 'none', - }, - }); - setOpenUserAction(null); - }, - icon: 'clear_status', - }, { allowed: allowedToMuteAudio && !isBreakout, key: 'mute', label: intl.formatMessage(messages.MuteUserAudioLabel), onClick: () => { - toggleVoice(user.userId, voiceToggle); + toggleVoice(user.userId, true, voiceToggle); setOpenUserAction(null); }, icon: 'mute', @@ -421,7 +392,7 @@ const UserActions: React.FC = ({ key: 'unmute', label: intl.formatMessage(messages.UnmuteUserAudioLabel), onClick: () => { - toggleVoice(user.userId, voiceToggle); + toggleVoice(user.userId, false, voiceToggle); setOpenUserAction(null); }, icon: 'unmute', @@ -541,40 +512,7 @@ const UserActions: React.FC = ({ )), ]; - const nestedOptions = [ - { - allowed: allowedToChangeStatus, - key: 'back', - label: intl.formatMessage(messages.backTriggerLabel), - onClick: () => setShowNestedOptions(false), - icon: 'left_arrow', - }, - { - allowed: showNestedOptions, - key: 'separator-01', - isSeparator: true, - }, - ...Object.keys(EMOJI_STATUSES).map((key) => ({ - allowed: showNestedOptions, - key, - label: intl.formatMessage({ id: `app.actionsBar.emojiMenu.${key}Label` }), - onClick: () => { - setEmojiStatus({ - variables: { - emoji: key, - }, - }); - setOpenUserAction(null); - setShowNestedOptions(false); - }, - icon: (EMOJI_STATUSES as Record)[key], - dataTest: key, - })), - ]; - - const actions = showNestedOptions - ? nestedOptions.filter((key) => key.allowed) - : dropdownOptions.filter((key) => key.allowed); + const actions = dropdownOptions.filter((key) => key.allowed); if (!actions.length) { return ( @@ -605,10 +543,8 @@ const UserActions: React.FC = ({ ) } actions={actions} - selectedEmoji={user.emoji} onCloseCallback={() => { setOpenUserAction(null); - setShowNestedOptions(false); }} open={open} /> diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/service.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/service.ts index bc62c887bb..c21e94face 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/service.ts +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/service.ts @@ -4,16 +4,8 @@ import { UsersPolicies, } from '/imports/ui/Types/meeting'; import Auth from '/imports/ui/services/auth'; -import { EMOJI_STATUSES } from '/imports/utils/statuses'; -import AudioService from '/imports/ui/components/audio/service'; import logger from '/imports/startup/client/logger'; - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore - temporary, while meteor exists in the project -const PIN_WEBCAM = window.meetingClientSettings.public.kurento.enableVideoPin; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore - temporary, while meteor exists in the project -const USER_STATUS_ENABLED = window.meetingClientSettings.public.userStatus.enabled; +import { toggleMuteMicrophone } from '/imports/ui/components/audio/audio-graphql/audio-controls/input-stream-live-selector/service'; export const isVoiceOnlyUser = (userId: string) => userId.toString().startsWith('v_'); @@ -25,6 +17,7 @@ export const generateActionsPermissions = ( lockSettings: LockSettings, usersPolicies: UsersPolicies, isBreakout: boolean, + isMuted: boolean, ) => { const subjectUserVoice = subjectUser.voice; @@ -37,19 +30,15 @@ export const generateActionsPermissions = ( const allowedToChatPrivately = !amISubjectUser && !isDialInUser; const allowedToMuteAudio = hasAuthority && subjectUserVoice?.joined - && !subjectUserVoice?.muted + && !isMuted && !subjectUserVoice?.listenOnly; const allowedToUnmuteAudio = hasAuthority && subjectUserVoice?.joined && !subjectUserVoice.listenOnly - && subjectUserVoice.muted + && isMuted && (amISubjectUser || usersPolicies?.allowModsToUnmuteUsers); - const allowedToResetStatus = hasAuthority - && subjectUser.emoji !== EMOJI_STATUSES.none - && !isDialInUser; - // if currentUser is a moderator, allow removing other users const allowedToRemove = amIModerator && !amISubjectUser @@ -69,8 +58,6 @@ export const generateActionsPermissions = ( && !isBreakout && !(isSubjectUserGuest && usersPolicies?.authenticatedGuest && !usersPolicies?.allowPromoteGuestToModerator); - const allowedToChangeStatus = amISubjectUser && USER_STATUS_ENABLED; - const allowedToChangeUserLockStatus = amIModerator && !isSubjectUserModerator && lockSettings?.hasActiveLockSetting; @@ -85,24 +72,18 @@ export const generateActionsPermissions = ( const allowedToSetPresenter = amIModerator && !subjectUser.presenter && !isDialInUser; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - temporary, while meteor exists in the project - const allowedToSetAway = amISubjectUser && !USER_STATUS_ENABLED; return { allowedToChatPrivately, allowedToMuteAudio, allowedToUnmuteAudio, - allowedToResetStatus, allowedToRemove, allowedToSetPresenter, allowedToPromote, allowedToDemote, - allowedToChangeStatus, allowedToChangeUserLockStatus, allowedToChangeWhiteboardAccess, allowedToEjectCameras, - allowedToSetAway, }; }; @@ -111,6 +92,8 @@ export const isVideoPinEnabledForCurrentUser = ( isBreakout: boolean, ) => { const { isModerator } = currentUser; + + const PIN_WEBCAM = window.meetingClientSettings.public.kurento.enableVideoPin; const isPinEnabled = PIN_WEBCAM; return !!(isModerator @@ -124,11 +107,11 @@ export const isVideoPinEnabledForCurrentUser = ( // so this code is duplicated from the old userlist service // session for chats the current user started -export const toggleVoice = (userId: string, voiceToggle: (userId?: string | null, muted?: boolean | null) => void) => { +export const toggleVoice = (userId: string, muted: boolean, voiceToggle: (userId: string, muted: boolean) => void) => { if (userId === Auth.userID) { - AudioService.toggleMuteMicrophone(voiceToggle); + toggleMuteMicrophone(!muted, voiceToggle); } else { - voiceToggle(userId); + voiceToggle(userId, muted); logger.info({ logCode: 'usermenu_option_mute_toggle_audio', extraInfo: { logType: 'moderator_action', userId }, diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx index 69e5167972..29810eb091 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx @@ -14,7 +14,7 @@ const intlMessages = defineMessages({ const UserPolls = ({ intl, - isPresenter, + isPresenter = false, pollIsOpen, forcePollOpen, sidebarContentPanel, @@ -49,6 +49,7 @@ const UserPolls = ({ role="button" tabIndex={0} data-test="pollMenuButton" + active={sidebarContentPanel === PANELS.POLL} onClick={handleClickTogglePoll} onKeyDown={(e) => { if (e.key === 'Enter') { @@ -75,7 +76,3 @@ UserPolls.propTypes = { pollIsOpen: PropTypes.bool.isRequired, forcePollOpen: PropTypes.bool.isRequired, }; - -UserPolls.defaultProps = { - isPresenter: false, -}; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/container.jsx index 9a6aebd3f7..3d15f74cc1 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/container.jsx @@ -1,25 +1,26 @@ import React from 'react'; -import { withTracker } from 'meteor/react-meteor-data'; import UserPolls from './component'; import { layoutSelectInput, layoutDispatch } from '../../../layout/context'; +import { useStorageKey } from '/imports/ui/services/storage/hooks'; const UserPollsContainer = (props) => { const sidebarContent = layoutSelectInput((i) => i.sidebarContent); const { sidebarContentPanel } = sidebarContent; const layoutContextDispatch = layoutDispatch(); + const pollIsOpen = useStorageKey('isPollOpen') || false; + const forcePollOpen = useStorageKey('forcePollOpen') || false; return ( ); }; -export default withTracker(() => ({ - pollIsOpen: Session.equals('isPollOpen', true), - forcePollOpen: Session.equals('forcePollOpen', true), -}))(UserPollsContainer); +export default UserPollsContainer; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-list-content/user-notes/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-list-content/user-notes/component.tsx index 4171918c49..016ade23a3 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-list-content/user-notes/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-list-content/user-notes/component.tsx @@ -1,5 +1,4 @@ import React, { useEffect, useState } from 'react'; -import { useSubscription } from '@apollo/client'; import { defineMessages, useIntl } from 'react-intl'; import Icon from '/imports/ui/components/common/icon/component'; import NotesService from '/imports/ui/components/notes/service'; @@ -16,8 +15,7 @@ import usePreviousValue from '/imports/ui/hooks/usePreviousValue'; import useRev from '/imports/ui/components/pads/pads-graphql/hooks/useRev'; import useNotesLastRev from '../../../../notes/hooks/useNotesLastRev'; import useHasUnreadNotes from '../../../../notes/hooks/useHasUnreadNotes'; - -const NOTES_CONFIG = window.meetingClientSettings.public.notes; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; const intlMessages = defineMessages({ title: { @@ -65,7 +63,7 @@ interface UserNotesGraphqlProps { markNotesAsRead: () => void, // eslint-disable-next-line @typescript-eslint/no-explicit-any toggleNotesPanel: (sidebarContentPanel: any, layoutContextDispatch: any) => void, - isEnabled: () => boolean, + isEnabled: boolean, } interface UserNotesContainerGraphqlProps { @@ -138,6 +136,8 @@ const UserNotesGraphql: React.FC = (props) => { aria-describedby="lockedNotes" role="button" tabIndex={0} + active={notesOpen} + data-test="sharedNotesButton" onClick={() => toggleNotesPanel(sidebarContentPanel, layoutContextDispatch)} // @ts-ignore onKeyDown={(e) => { @@ -173,7 +173,7 @@ const UserNotesGraphql: React.FC = (props) => { ); }; - if (!isEnabled()) return null; + if (!isEnabled) return null; return ( @@ -194,7 +194,10 @@ const UserNotesGraphql: React.FC = (props) => { const UserNotesContainerGraphql: React.FC = (props) => { const { userLocks } = props; const disableNotes = userLocks.userNotes; - const { data: pinnedPadData } = useSubscription(PINNED_PAD_SUBSCRIPTION); + const { data: pinnedPadData } = useDeduplicatedSubscription(PINNED_PAD_SUBSCRIPTION); + + const NOTES_CONFIG = window.meetingClientSettings.public.notes; + const isPinned = !!pinnedPadData && pinnedPadData.sharedNotes[0]?.sharedNotesExtId === NOTES_CONFIG.id; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -202,11 +205,12 @@ const UserNotesContainerGraphql: React.FC = (pro const { sidebarContentPanel } = sidebarContent; const layoutContextDispatch = layoutDispatch(); - const rev = useRev(NotesService.ID); + const rev = useRev(NOTES_CONFIG.id); const { setNotesLastRev } = useNotesLastRev(); const hasUnreadNotes = useHasUnreadNotes(); const markNotesAsRead = () => setNotesLastRev(rev); + const isEnabled = NotesService.useIsEnabled(); return ( = (pro hasUnreadNotes={hasUnreadNotes} markNotesAsRead={markNotesAsRead} toggleNotesPanel={NotesService.toggleNotesPanel} - isEnabled={NotesService.isEnabled} + isEnabled={isEnabled} /> ); }; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-list-content/user-notes/styles.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-list-content/user-notes/styles.ts index 7ac236aeea..84a4a72e91 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-list-content/user-notes/styles.ts +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-list-content/user-notes/styles.ts @@ -15,6 +15,10 @@ const UnreadMessagesText = styled(StyledContent.UnreadMessagesText)``; const ListItem = styled(StyledContent.ListItem)` i{ left: 4px; } + + :disabled { + border: none; + } `; const NotesTitle = styled.div` diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/component.tsx index 1b175f6bbe..01fd09b11f 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/component.tsx @@ -1,12 +1,14 @@ import React from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { USER_AGGREGATE_COUNT_SUBSCRIPTION } from '/imports/ui/core/graphql/queries/users'; -import { useSubscription } from '@apollo/client'; import UserTitleOptionsContainer from './user-options-dropdown/component'; import Styled from './styles'; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; +import { USER_WITH_AUDIO_AGGREGATE_COUNT_SUBSCRIPTION } from './queries'; interface UserTitleProps { count: number; + countWithAudio: number; } const messages = defineMessages({ @@ -18,13 +20,19 @@ const messages = defineMessages({ const UserTitle: React.FC = ({ count, + countWithAudio, }) => { const intl = useIntl(); return ( {intl.formatMessage(messages.usersTitle)} - {` (${count.toLocaleString('en-US', { notation: 'standard' })})`} + + {` (${count.toLocaleString('en-US', { notation: 'standard' })})`} + @@ -34,9 +42,19 @@ const UserTitle: React.FC = ({ const UserTitleContainer: React.FC = () => { const { data: countData, - } = useSubscription(USER_AGGREGATE_COUNT_SUBSCRIPTION); + } = useDeduplicatedSubscription(USER_AGGREGATE_COUNT_SUBSCRIPTION); + const { + data: audioUsersCountData, + } = useDeduplicatedSubscription(USER_WITH_AUDIO_AGGREGATE_COUNT_SUBSCRIPTION); const count = countData?.user_aggregate?.aggregate?.count || 0; - return ; + const countWithAudio = audioUsersCountData?.user_aggregate?.aggregate?.count || 0; + + return ( + + ); }; export default UserTitleContainer; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/guest-panel-opener/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/guest-panel-opener/component.tsx index 499d81c25c..1b046264fd 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/guest-panel-opener/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/guest-panel-opener/component.tsx @@ -1,7 +1,6 @@ import React, { useCallback } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import { useMeeting } from '/imports/ui/core/hooks/useMeeting'; -import { useSubscription } from '@apollo/client'; import { GET_GUESTS_COUNT, GuestUsersCountResponse } from './queries'; import { layoutDispatch, layoutSelectInput } from '/imports/ui/components/layout/context'; import { Input } from '/imports/ui/components/layout/layoutTypes'; @@ -9,8 +8,7 @@ import { ACTIONS, PANELS } from '/imports/ui/components/layout/enums'; import Icon from '/imports/ui/components/common/icon/icon-ts/component'; import Styled from './styles'; import logger from '/imports/startup/client/logger'; - -const ALWAYS_SHOW_WAITING_ROOM = window.meetingClientSettings.public.app.alwaysShowWaitingRoomUI; +import useDeduplicatedSubscription from '/imports/ui/core/hooks/useDeduplicatedSubscription'; interface GuestPanelOpenerProps { count: number; @@ -96,7 +94,7 @@ const GuestPanelOpenerContainer: React.FC = () => { data: guestsCountData, loading: guestsCountLoading, error: guestsCountError, - } = useSubscription(GET_GUESTS_COUNT); + } = useDeduplicatedSubscription(GET_GUESTS_COUNT); if (guestsCountError) { logger.error(guestsCountError); @@ -111,6 +109,8 @@ const GuestPanelOpenerContainer: React.FC = () => { if (guestsCountLoading || !currentMeeting) return null; + const ALWAYS_SHOW_WAITING_ROOM = window.meetingClientSettings.public.app.alwaysShowWaitingRoomUI; + const showWaitingRoom = (ALWAYS_SHOW_WAITING_ROOM && currentMeeting?.usersPolicies?.guestPolicy === 'ASK_MODERATOR') || (guestsCountData?.user_guest_aggregate.aggregate.count || 0) > 0; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/queries.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/queries.ts new file mode 100644 index 0000000000..cb4bb82076 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/queries.ts @@ -0,0 +1,15 @@ +import { gql } from '@apollo/client'; + +export const USER_WITH_AUDIO_AGGREGATE_COUNT_SUBSCRIPTION = gql` + subscription UsersWithAudioCount { + user_aggregate(where: {voice: {joined: {_eq: true}}}) { + aggregate { + count + } + } + } +`; + +export default { + USER_WITH_AUDIO_AGGREGATE_COUNT_SUBSCRIPTION, +}; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/component.tsx index c8a2739878..9c6313a508 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/component.tsx @@ -20,12 +20,10 @@ import { } from './service'; import { User } from '/imports/ui/Types/user'; import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; -import { isBreakoutRoomsEnabled, isLearningDashboardEnabled } from '/imports/ui/services/features'; +import { useIsBreakoutRoomsEnabled, useIsLearningDashboardEnabled } from '/imports/ui/services/features'; import { useMutation, useLazyQuery } from '@apollo/client'; -import { CLEAR_ALL_EMOJI } from '/imports/ui/core/graphql/mutations/userMutations'; import { SET_MUTED } from './mutations'; import { GET_USER_NAMES } from '/imports/ui/core/graphql/queries/users'; -import { notify } from '/imports/ui/services/notification'; import logger from '/imports/startup/client/logger'; const intlMessages = defineMessages({ @@ -33,10 +31,6 @@ const intlMessages = defineMessages({ id: 'app.userList.userOptions.manageUsersLabel', description: 'Manage user label', }, - clearAllLabel: { - id: 'app.userList.userOptions.clearAllLabel', - description: 'Clear all label', - }, clearAllDesc: { id: 'app.userList.userOptions.clearAllDesc', description: 'Clear all description', @@ -105,16 +99,16 @@ const intlMessages = defineMessages({ id: 'app.modal.newTab', description: 'label used in aria description', }, - clearStatusMessage: { - id: 'app.userList.content.participants.options.clearedStatus', - description: 'Used in toast notification when emojis have been cleared', + invitationLabel: { + id: 'app.actionsBar.actionsDropdown.breakoutRoomInvitationLabel', + description: 'Invitation item', + }, + invitationDesc: { + id: 'app.actionsBar.actionsDropdown.breakoutRoomInvitationDesc', + description: 'Invitation item description', }, }); -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore - temporary, while meteor exists in the project -const { dynamicGuestPolicy } = window.meetingClientSettings.public.app; - interface RenderModalProps { setIsOpen: React.Dispatch>; isOpen: boolean; @@ -150,6 +144,7 @@ interface UserTitleOptionsProps { isModerator: boolean; hasBreakoutRooms: boolean | undefined; meetingName: string | undefined; + learningDashboardToken: string | undefined; } const UserTitleOptions: React.FC = ({ @@ -159,6 +154,7 @@ const UserTitleOptions: React.FC = ({ isModerator, hasBreakoutRooms, meetingName, + learningDashboardToken, }) => { const intl = useIntl(); const { locale } = intl; @@ -177,10 +173,15 @@ const UserTitleOptions: React.FC = ({ const [isGuestPolicyModalOpen, setGuestPolicyModalIsOpen] = useState(false); const [isLockViewersModalOpen, setLockViewersModalIsOpen] = useState(false); - const [clearAllEmoji] = useMutation(CLEAR_ALL_EMOJI); const [setMuted] = useMutation(SET_MUTED); const [getUsers, { data: usersData, error: usersError }] = useLazyQuery(GET_USER_NAMES, { fetchPolicy: 'no-cache' }); const users = usersData?.user || []; + const isLearningDashboardEnabled = useIsLearningDashboardEnabled(); + const isBreakoutRoomsEnabled = useIsBreakoutRoomsEnabled(); + const canInviteUsers = isModerator + && !isBreakout + && hasBreakoutRooms; + const isInvitation = hasBreakoutRooms && isModerator; if (usersError) { logger.error({ @@ -196,11 +197,6 @@ const UserTitleOptions: React.FC = ({ } }, [users]); - const toggleStatus = () => { - clearAllEmoji(); - notify(intl.formatMessage(intlMessages.clearStatusMessage), 'info', 'clear_status'); - }; - const toggleMute = (muted: boolean, exceptPresenter: boolean) => { setMuted({ variables: { @@ -230,11 +226,13 @@ const UserTitleOptions: React.FC = ({ ); }; + const { dynamicGuestPolicy } = window.meetingClientSettings.public.app; + const actions = useMemo(() => { const canCreateBreakout = isModerator && !isBreakout && !hasBreakoutRooms - && isBreakoutRoomsEnabled(); + && isBreakoutRoomsEnabled; return [ { allow: !isBreakout, @@ -280,14 +278,6 @@ const UserTitleOptions: React.FC = ({ icon: 'download', dataTest: 'downloadUserNamesList', }, - { - allow: true, - key: uuids.current[5], - label: intl.formatMessage(intlMessages.clearAllLabel), - description: intl.formatMessage(intlMessages.clearAllDesc), - onClick: () => toggleStatus(), - icon: 'clear_status', - }, { key: 'separator-01', isSeparator: true, @@ -303,24 +293,33 @@ const UserTitleOptions: React.FC = ({ dataTest: 'createBreakoutRooms', }, { - key: 'separator-02', - isSeparator: true, - allow: true, + allow: canInviteUsers, + key: uuids.current[7], + icon: 'rooms', + label: intl.formatMessage(intlMessages.invitationLabel), + description: intl.formatMessage(intlMessages.invitationDesc), + onClick: () => setCreateBreakoutRoomModalIsOpen(true), + dataTest: 'inviteUsers', }, { - allow: isLearningDashboardEnabled(), + key: 'separator-02', + isSeparator: true, + allow: canCreateBreakout, + }, + { + allow: isLearningDashboardEnabled, icon: 'multi_whiteboard', iconRight: 'popout_window', label: intl.formatMessage(intlMessages.learningDashboardLabel), description: `${intl.formatMessage(intlMessages.learningDashboardDesc)} ${intl.formatMessage(intlMessages.newTab)}`, key: uuids.current[8], - onClick: () => { openLearningDashboardUrl(locale); }, + onClick: () => { openLearningDashboardUrl(locale, learningDashboardToken); }, dividerTop: true, dataTest: 'learningDashboard', }, ].filter(({ allow }) => allow); - }, [isModerator, hasBreakoutRooms, isMeetingMuted, locale]); + }, [isModerator, hasBreakoutRooms, isMeetingMuted, locale, intl, isBreakoutRoomsEnabled, isLearningDashboardEnabled]); const newLocal = 'true'; return ( @@ -355,7 +354,9 @@ const UserTitleOptions: React.FC = ({ setIsOpen: setCreateBreakoutRoomModalIsOpen, priority: 'medium', Component: CreateBreakoutRoomContainerGraphql, - otherOptions: {}, + otherOptions: { + isUpdate: isInvitation, + }, })} {renderModal({ @@ -383,8 +384,9 @@ const UserTitleOptionsContainer: React.FC = () => { const { data: meetingInfo } = useMeeting((meeting: Partial) => ({ voiceSettings: meeting?.voiceSettings, isBreakout: meeting?.isBreakout, - breakoutPolicies: meeting?.breakoutPolicies, + componentsFlags: meeting?.componentsFlags, name: meeting?.name, + learningDashboardAccessToken: meeting.learningDashboardAccessToken, })); const { data: currentUser } = useCurrentUser((user: Partial) => ({ @@ -394,15 +396,17 @@ const UserTitleOptionsContainer: React.FC = () => { // in case of current user isn't load yet if (!currentUser?.isModerator ?? true) return null; + const hasBreakoutRooms = meetingInfo?.componentsFlags?.hasBreakoutRoom ?? false; + return ( 0} + hasBreakoutRooms={hasBreakoutRooms} meetingName={meetingInfo?.name} + learningDashboardToken={meetingInfo?.learningDashboardAccessToken} /> ); }; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/service.ts b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/service.ts index 7835006667..89ab00a3ca 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/service.ts +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/service.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ import { getUserNamesLink } from '/imports/ui/components/user-list/service'; -import Settings from '/imports/ui/services/settings'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import LearningDashboardService from '/imports/ui/components/learning-dashboard/service'; import { defineMessages, IntlShape } from 'react-intl'; import { User } from '/imports/ui/Types/user'; @@ -21,6 +21,7 @@ const intlMessages = defineMessages({ }); export const onSaveUserNames = (intl: IntlShape, meetingName: string, users: [User]) => { + const Settings = getSettingsSingletonInstance(); // @ts-ignore - temporary while settings are still in .js const lang = Settings.application.locale; const date = new Date(); @@ -36,7 +37,11 @@ export const onSaveUserNames = (intl: IntlShape, meetingName: string, users: [Us intl.formatMessage(intlMessages.sortedFirstNameHeading), intl.formatMessage(intlMessages.sortedLastNameHeading), users, + meetingName, ).dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })); }; -export const openLearningDashboardUrl = (lang: string) => LearningDashboardService.openLearningDashboardUrl(lang); +export const openLearningDashboardUrl = ( + lang: string, + token?: string, +) => LearningDashboardService.openLearningDashboardUrl(lang, token); diff --git a/bigbluebutton-html5/imports/ui/components/user-reaction/service.js b/bigbluebutton-html5/imports/ui/components/user-reaction/service.js index b4aee779ac..6338a8c8ad 100644 --- a/bigbluebutton-html5/imports/ui/components/user-reaction/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-reaction/service.js @@ -1,10 +1,10 @@ import getFromUserSettings from '/imports/ui/services/users-settings'; -import { isReactionsEnabled } from '/imports/ui/services/features/index'; +import { useIsReactionsEnabled } from '/imports/ui/services/features/index'; -const ENABLED = window.meetingClientSettings.public.userReaction.enabled; +const getEnabledSetting = () => window.meetingClientSettings.public.userReaction.enabled; -const isEnabled = () => isReactionsEnabled() && getFromUserSettings('enable-user-reaction', ENABLED); +const useIsEnabled = () => useIsReactionsEnabled() && getFromUserSettings('enable-user-reaction', getEnabledSetting()); export default { - isEnabled, + useIsEnabled, }; diff --git a/bigbluebutton-html5/imports/ui/components/video-preview/component.jsx b/bigbluebutton-html5/imports/ui/components/video-preview/component.jsx index 01e26e5e31..efcd18d2ed 100755 --- a/bigbluebutton-html5/imports/ui/components/video-preview/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/video-preview/component.jsx @@ -8,21 +8,26 @@ import VirtualBgSelector from '/imports/ui/components/video-preview/virtual-back import logger from '/imports/startup/client/logger'; import browserInfo from '/imports/utils/browserInfo'; import PreviewService from './service'; -import VideoService from '../video-provider/video-provider-graphql/service'; +import VideoService from '/imports/ui/components/video-provider/service'; import Styled from './styles'; import deviceInfo from '/imports/utils/deviceInfo'; import MediaStreamUtils from '/imports/utils/media-stream-utils'; import { notify } from '/imports/ui/services/notification'; import { EFFECT_TYPES, - SHOW_THUMBNAILS, setSessionVirtualBackgroundInfo, getSessionVirtualBackgroundInfo, + removeSessionVirtualBackgroundInfo, isVirtualBackgroundSupported, + getSessionVirtualBackgroundInfoWithDefault, } from '/imports/ui/services/virtual-background/service'; -import Settings from '/imports/ui/services/settings'; -import { isVirtualBackgroundsEnabled } from '/imports/ui/services/features'; +import { getSettingsSingletonInstance } from '/imports/ui/services/settings'; import Checkbox from '/imports/ui/components/common/checkbox/component' +import AppService from '/imports/ui/components/app/service'; +import { CustomVirtualBackgroundsContext } from '/imports/ui/components/video-preview/virtual-background/context'; +import VBGSelectorService from '/imports/ui/components/video-preview/virtual-background/service'; +import Storage from '/imports/ui/services/storage/session'; +import getFromUserSettings from '/imports/ui/services/users-settings'; const VIEW_STATES = { finding: 'finding', @@ -30,9 +35,6 @@ const VIEW_STATES = { error: 'error', }; -const ENABLE_CAMERA_BRIGHTNESS = window.meetingClientSettings.public.app.enableCameraBrightness; -const CAMERA_BRIGHTNESS_AVAILABLE = ENABLE_CAMERA_BRIGHTNESS && isVirtualBackgroundSupported(); - const propTypes = { intl: PropTypes.object.isRequired, closeModal: PropTypes.func.isRequired, @@ -53,9 +55,9 @@ const defaultProps = { }; const intlMessages = defineMessages({ - webcamEffectsTitle: { - id: 'app.videoPreview.webcamEffectsTitle', - description: 'Title for the video effects modal', + webcamVirtualBackgroundTitle: { + id: 'app.videoPreview.webcamVirtualBackgroundLabel', + description: 'Title for the virtual background modal', }, webcamSettingsTitle: { id: 'app.videoPreview.webcamSettingsTitle', @@ -65,6 +67,10 @@ const intlMessages = defineMessages({ id: 'app.videoPreview.closeLabel', description: 'Close button label', }, + cancelLabel: { + id: 'app.mobileAppModal.dismissLabel', + description: 'Close button label', + }, webcamPreviewLabel: { id: 'app.videoPreview.webcamPreviewLabel', description: 'Webcam preview label', @@ -216,6 +222,8 @@ const intlMessages = defineMessages({ }); class VideoPreview extends Component { + static contextType = CustomVirtualBackgroundsContext; + constructor(props) { super(props); @@ -232,11 +240,13 @@ class VideoPreview extends Component { this.handleVirtualBgSelected = this.handleVirtualBgSelected.bind(this); this.handleLocalStreamInactive = this.handleLocalStreamInactive.bind(this); this.handleBrightnessAreaChange = this.handleBrightnessAreaChange.bind(this); + this.handleSelectTab = this.handleSelectTab.bind(this); this._isMounted = false; this.state = { webcamDeviceId, + selectedTab: 0, availableWebcams: null, selectedProfile: null, isStartSharingDisabled: true, @@ -245,6 +255,7 @@ class VideoPreview extends Component { previewError: null, brightness: 100, wholeImageBrightness: false, + skipPreviewFailed: false, }; } @@ -264,6 +275,13 @@ class VideoPreview extends Component { return this._currentVideoStream; } + shouldSkipVideoPreview() { + const { skipPreviewFailed } = this.state; + const { forceOpen } = this.props; + + return PreviewService.getSkipVideoPreview() && !forceOpen && !skipPreviewFailed; + } + componentDidMount() { const { webcamDeviceId, @@ -273,10 +291,31 @@ class VideoPreview extends Component { this._isMounted = true; if (deviceInfo.hasMediaDevices) { - navigator.mediaDevices.enumerateDevices().then((devices) => { + navigator.mediaDevices.enumerateDevices().then(async (devices) => { VideoService.updateNumberOfDevices(devices); - // Video preview skip is activated, short circuit via a simpler procedure - if (PreviewService.getSkipVideoPreview() && !forceOpen) return this.skipVideoPreview(); + // Tries to skip video preview - this can happen if: + // 1. skipVideoPreview, skipVideoPreviewOnFirstJoin, or + // skipVideoPreviewIfPreviousDevice flags are enabled and meet their + // own conditions + // 2. forceOpen flag was not specified to this component + // + // This will fail if no skip conditions are met, or if an unexpected + // failure occurs during the process. In that case, the error will be + // handled and the component will display the default video preview UI + if (this.shouldSkipVideoPreview()) { + try { + await this.skipVideoPreview() + return; + } catch (error) { + logger.warn({ + logCode: 'video_preview_skip_failure', + extraInfo: { + errorName: error.name, + errorMessage: error.message, + }, + }, 'Skipping video preview failed'); + } + } // Late enumerateDevices resolution, stop. if (!this._isMounted) return; @@ -295,37 +334,35 @@ class VideoPreview extends Component { }, `Enumerate devices came back. There are ${devices.length} devices and ${webcams.length} are video inputs`); if (webcams.length > 0) { - this.getInitialCameraStream(webcams[0].deviceId) - .then(async () => { - // Late gUM resolve, stop. - if (!this._isMounted) return; + await this.getInitialCameraStream(webcams[0].deviceId); + // Late gUM resolve, stop. + if (!this._isMounted) return; - if (!areLabelled || !areIdentified) { - // If they aren't labelled or have nullish deviceIds, run - // enumeration again and get their full versions - // Why: fingerprinting countermeasures obfuscate those when - // no permission was granted via gUM - try { - const newDevices = await navigator.mediaDevices.enumerateDevices(); - webcams = PreviewService.digestVideoDevices(newDevices, webcamDeviceId).webcams; - } catch (error) { - // Not a critical error because it should only affect UI; log it - // and go ahead - logger.error({ - logCode: 'video_preview_enumerate_relabel_failure', - extraInfo: { - errorName: error.name, errorMessage: error.message, - }, - }, 'enumerateDevices for relabelling failed'); - } - } + if (!areLabelled || !areIdentified) { + // If they aren't labelled or have nullish deviceIds, run + // enumeration again and get their full versions + // Why: fingerprinting countermeasures obfuscate those when + // no permission was granted via gUM + try { + const newDevices = await navigator.mediaDevices.enumerateDevices(); + webcams = PreviewService.digestVideoDevices(newDevices, webcamDeviceId).webcams; + } catch (error) { + // Not a critical error beucase it should only affect UI; log it + // and go ahead + logger.error({ + logCode: 'video_preview_enumerate_relabel_failure', + extraInfo: { + errorName: error.name, errorMessage: error.message, + }, + }, 'enumerateDevices for relabelling failed'); + } + } - this.setState({ - availableWebcams: webcams, - viewState: VIEW_STATES.found, - }); - this.displayPreview(); - }); + this.setState({ + availableWebcams: webcams, + viewState: VIEW_STATES.found, + }); + this.displayPreview(); } else { // There were no webcams coming from enumerateDevices. Throw an error. const noWebcamsError = new Error('NotFoundError'); @@ -367,8 +404,11 @@ class VideoPreview extends Component { this._isMounted = false; } - startCameraBrightness() { - if (CAMERA_BRIGHTNESS_AVAILABLE) { + async startCameraBrightness() { + const ENABLE_CAMERA_BRIGHTNESS = window.meetingClientSettings.public.app.enableCameraBrightness; + const CAMERA_BRIGHTNESS_AVAILABLE = ENABLE_CAMERA_BRIGHTNESS && isVirtualBackgroundSupported(); + + if (CAMERA_BRIGHTNESS_AVAILABLE && this.currentVideoStream) { const setBrightnessInfo = () => { const stream = this.currentVideoStream || {}; const service = stream.virtualBgService || {}; @@ -377,20 +417,31 @@ class VideoPreview extends Component { }; if (!this.currentVideoStream.virtualBgService) { - this.startVirtualBackground( + const switched = await this.startVirtualBackground( this.currentVideoStream, EFFECT_TYPES.NONE_TYPE, - ).then((switched) => { - if (switched) { - setBrightnessInfo(); - } - }); + ); + if (switched) setBrightnessInfo(); } else { setBrightnessInfo(); } } } + async setCameraBrightness(brightness) { + const ENABLE_CAMERA_BRIGHTNESS = window.meetingClientSettings.public.app.enableCameraBrightness; + const CAMERA_BRIGHTNESS_AVAILABLE = ENABLE_CAMERA_BRIGHTNESS && isVirtualBackgroundSupported(); + + if (CAMERA_BRIGHTNESS_AVAILABLE && this.currentVideoStream) { + if (this.currentVideoStream?.virtualBgService == null) { + await this.startCameraBrightness(); + } + + this.currentVideoStream.changeCameraBrightness(brightness); + this.setState({ brightness }); + } + } + handleSelectWebcam(event) { const webcamValue = event.target.value; @@ -415,28 +466,31 @@ class VideoPreview extends Component { } } - updateVirtualBackgroundInfo = () => { + updateVirtualBackgroundInfo () { const { webcamDeviceId } = this.state; - // Update this session's virtual camera effect information if it's enabled - setSessionVirtualBackgroundInfo( - this.currentVideoStream.virtualBgType, - this.currentVideoStream.virtualBgName, - webcamDeviceId, - ); + if (this.currentVideoStream) { + setSessionVirtualBackgroundInfo( + webcamDeviceId, + this.currentVideoStream.virtualBgType, + this.currentVideoStream.virtualBgName, + this.currentVideoStream.virtualBgUniqueId, + ); + } }; // Resolves into true if the background switch is successful, false otherwise handleVirtualBgSelected(type, name, customParams) { const { sharedDevices } = this.props; - const { webcamDeviceId } = this.state; + const { webcamDeviceId, brightness } = this.state; const shared = this.isAlreadyShared(webcamDeviceId); - if (type !== EFFECT_TYPES.NONE_TYPE || CAMERA_BRIGHTNESS_AVAILABLE) { + const ENABLE_CAMERA_BRIGHTNESS = window.meetingClientSettings.public.app.enableCameraBrightness; + const CAMERA_BRIGHTNESS_AVAILABLE = ENABLE_CAMERA_BRIGHTNESS && isVirtualBackgroundSupported(); + + if (type !== EFFECT_TYPES.NONE_TYPE || CAMERA_BRIGHTNESS_AVAILABLE && brightness !== 100) { return this.startVirtualBackground(this.currentVideoStream, type, name, customParams).then((switched) => { - // If it's not shared we don't have to update here because - // it will be updated in the handleStartSharing method. - if (switched && shared) this.updateVirtualBackgroundInfo(); + if (switched) this.updateVirtualBackgroundInfo(); return switched; }); } else { @@ -479,7 +533,7 @@ class VideoPreview extends Component { }); } - handleStartSharing() { + async handleStartSharing() { const { resolve, startSharing, @@ -507,17 +561,18 @@ class VideoPreview extends Component { this.stopVirtualBackground(this.currentVideoStream); } - this.updateVirtualBackgroundInfo(); - this.cleanupStreamAndVideo(); - - PreviewService.changeProfile(selectedProfile); - PreviewService.changeWebcam(webcamDeviceId); - if (cameraAsContent) { - startSharingCameraAsContent(webcamDeviceId); - } else { + if (!cameraAsContent) { + // Store selected profile, camera ID and virtual background in the storage + // for future use + PreviewService.changeProfile(selectedProfile); + PreviewService.changeWebcam(webcamDeviceId); + this.updateVirtualBackgroundInfo(); + this.cleanupStreamAndVideo(); startSharing(webcamDeviceId); + } else { + this.cleanupStreamAndVideo(); + startSharingCameraAsContent(webcamDeviceId); } - if (resolve) resolve(); } handleStopSharing() { @@ -541,12 +596,12 @@ class VideoPreview extends Component { } handleProceed() { - const { resolve, closeModal, sharedDevices, isVisualEffects } = this.props; + const { resolve, closeModal, sharedDevices } = this.props; const { webcamDeviceId, brightness } = this.state; const shared = sharedDevices.includes(webcamDeviceId); if ( - (shared || isVisualEffects) + (shared) && this.currentVideoStream.virtualBgService && brightness === 100 && this.currentVideoStream.virtualBgType === EFFECT_TYPES.NONE_TYPE @@ -650,13 +705,85 @@ class VideoPreview extends Component { const { cameraAsContent } = this.props; const defaultProfile = !cameraAsContent ? PreviewService.getDefaultProfile() : PreviewService.getCameraAsContentProfile(); - return this.getCameraStream(deviceId, defaultProfile).then(() => { - this.updateDeviceId(deviceId); + return this.getCameraStream(deviceId, defaultProfile); + } + + applyStoredVirtualBg(deviceId = null) { + const webcamDeviceId = deviceId || this.state.webcamDeviceId; + + // Apply the virtual background stored in Local/Session Storage, if any + // If it fails, remove the stored background. + return new Promise((resolve, reject) => { + let customParams; + const virtualBackground = getSessionVirtualBackgroundInfo(webcamDeviceId); + + if (virtualBackground) { + const { type, name, uniqueId } = virtualBackground; + const handleFailure = (error) => { + this.handleVirtualBgError(error, type, name); + removeSessionVirtualBackgroundInfo(webcamDeviceId); + reject(error); + }; + const applyCustomVirtualBg = (backgrounds) => { + const background = backgrounds[uniqueId] + || Object.values(backgrounds).find(bg => bg.uniqueId === uniqueId); + + if (background && background.data) { + customParams = { + uniqueId, + file: background?.data, + }; + } else { + handleFailure(new Error('Missing virtual background data')); + return; + } + + this.handleVirtualBgSelected(type, name, customParams).then(resolve, handleFailure); + }; + + // If uniqueId is defined, this is a custom background. Fetch the custom + // params from the context and apply them + if (uniqueId) { + if (this.context.backgrounds[uniqueId]) { + applyCustomVirtualBg(this.context.backgrounds); + } else if (!this.context.loaded) { + // Virtual BG context might not be loaded yet (in case this is + // skipping the video preview). Load it manually. + VBGSelectorService.load(handleFailure, applyCustomVirtualBg); + } else { + handleFailure(new Error('Missing virtual background')); + } + + return; + } + + // Built-in background, just apply it. + this.handleVirtualBgSelected(type, name, customParams).then(resolve, handleFailure); + } else if (this.context.backgrounds.webcamBackgroundURL) { + // Apply custom background from JOIN URL parameter automatically + // only if there's not any session background yet. + const { filename, data, type, uniqueId } = this.context.backgrounds.webcamBackgroundURL; + const customParams = { + file: data, + uniqueId, + }; + + const handleFailure = (error) => { + this.handleVirtualBgError(error, type, filename); + removeSessionVirtualBackgroundInfo(webcamDeviceId); + reject(error); + }; + + this.handleVirtualBgSelected(type, filename, customParams).then(resolve, handleFailure); + } else { + resolve(); + } }); } - getCameraStream(deviceId, profile) { + async getCameraStream(deviceId, profile) { const { webcamDeviceId } = this.state; + const { cameraAsContent, forceOpen } = this.props; this.setState({ selectedProfile: profile.id, @@ -667,25 +794,42 @@ class VideoPreview extends Component { this.terminateCameraStream(this.currentVideoStream, webcamDeviceId); this.cleanupStreamAndVideo(); - // The return of doGUM is an instance of BBBVideoStream (a thin wrapper over a MediaStream) - return PreviewService.doGUM(deviceId, profile).then((bbbVideoStream) => { - // Late GUM resolve, clean up tracks, stop. - if (!this._isMounted) return this.terminateCameraStream(bbbVideoStream, deviceId); - + try { + // The return of doGUM is an instance of BBBVideoStream (a thin wrapper over a MediaStream) + const bbbVideoStream = await PreviewService.doGUM(deviceId, profile); this.currentVideoStream = bbbVideoStream; - this.startCameraBrightness(); - this.setState({ - isStartSharingDisabled: false, - }); - }).catch((error) => { + this.updateDeviceId(deviceId); + } catch(error) { // When video preview is set to skip, we need some way to bubble errors // up to users; so re-throw the error - if (!PreviewService.getSkipVideoPreview()) { + if (!this.shouldSkipVideoPreview()) { this.handlePreviewError('do_gum_preview', error, 'displaying final selection'); } else { throw error; } - }); + } + + // Restore virtual background if it was stored in Local/Session Storage + try { + if (!cameraAsContent) await this.applyStoredVirtualBg(deviceId); + } catch (error) { + // Only bubble up errors in this case if we're skipping the video preview + // This is because virtual background failures are deemed critical when + // skipping the video preview, but not otherwise + if (this.shouldSkipVideoPreview()) { + throw error; + } + } finally { + // Late VBG resolve, clean up tracks, stop. + if (!this._isMounted) { + this.terminateCameraStream(bbbVideoStream, deviceId); + this.cleanupStreamAndVideo(); + return; + } + this.setState({ + isStartSharingDisabled: false, + }); + } } displayPreview() { @@ -695,11 +839,20 @@ class VideoPreview extends Component { } skipVideoPreview() { - this.getInitialCameraStream().then(() => { + const { webcamDeviceId } = this.state; + const { forceOpen } = this.props; + + return this.getInitialCameraStream(webcamDeviceId).then(() => { this.handleStartSharing(); }).catch(error => { + PreviewService.clearWebcamDeviceId(); + PreviewService.clearWebcamProfileId(); + removeSessionVirtualBackgroundInfo(webcamDeviceId); this.cleanupStreamAndVideo(); - notify(this.handleGUMError(error), 'error', 'video'); + // Mark the skip as failed so that the component will override any option + // to skip the video preview and display the default UI + if (this._isMounted) this.setState({ skipPreviewFailed: true }); + throw error; }); } @@ -739,7 +892,6 @@ class VideoPreview extends Component { const { intl, sharedDevices, - isVisualEffects, cameraAsContent, } = this.props; @@ -749,133 +901,125 @@ class VideoPreview extends Component { selectedProfile, } = this.state; - const shared = sharedDevices.includes(webcamDeviceId); - const shouldShowVirtualBackgrounds = isVirtualBackgroundsEnabled() && !cameraAsContent; + return ( + + + {intl.formatMessage(intlMessages.cameraLabel)} + + { availableWebcams && availableWebcams.length > 0 + ? ( + + {availableWebcams.map((webcam, index) => ( + + ))} + + ) + : ( + + {intl.formatMessage(intlMessages.webcamNotFoundLabel)} + + ) + } + {this.renderQualitySelector()} + + ); + } - if (isVisualEffects) { + renderQualitySelector() { + const { + intl, + cameraAsContent, + } = this.props + + const { + selectedProfile, + availableWebcams, + webcamDeviceId, + } = this.state; + + const shared = this.isAlreadyShared(webcamDeviceId); + + if (shared) { return ( - <> - {isVirtualBackgroundsEnabled() && this.renderVirtualBgSelector()} - + + {intl.formatMessage(intlMessages.sharedCameraLabel)} + ); } + + if (cameraAsContent) return; + + const CAMERA_PROFILES = window.meetingClientSettings.public.kurento.cameraProfiles || []; + // Filtered, without hidden profiles + const PREVIEW_CAMERA_PROFILES = CAMERA_PROFILES.filter(p => !p.hidden); return ( <> + + {intl.formatMessage(intlMessages.qualityLabel)} + + {PREVIEW_CAMERA_PROFILES.length > 0 + ? ( + + {PREVIEW_CAMERA_PROFILES.map((profile) => { + const label = intlMessages[`${profile.id}`] + ? intl.formatMessage(intlMessages[`${profile.id}`]) + : profile.name; - { cameraAsContent - ? ( - <> - - {intl.formatMessage(intlMessages.cameraLabel)} - - { availableWebcams && availableWebcams.length > 0 - ? ( - - {availableWebcams.map((webcam, index) => ( - - ))} - - ) - : ( - - {intl.formatMessage(intlMessages.webcamNotFoundLabel)} - - ) - } - - ) - : - <> - - {intl.formatMessage(intlMessages.cameraLabel)} - - { availableWebcams && availableWebcams.length > 0 - ? ( - - {availableWebcams.map((webcam, index) => ( - - ))} - - ) - : ( - - {intl.formatMessage(intlMessages.webcamNotFoundLabel)} - - ) - } - { shared - ? ( - - {intl.formatMessage(intlMessages.sharedCameraLabel)} - - ) - : ( - <> - - {intl.formatMessage(intlMessages.qualityLabel)} - - {PreviewService.PREVIEW_CAMERA_PROFILES.length > 0 - ? ( - - {PreviewService.PREVIEW_CAMERA_PROFILES.map((profile) => { - const label = intlMessages[`${profile.id}`] - ? intl.formatMessage(intlMessages[`${profile.id}`]) - : profile.name; - - return ( - - ); - })} - - ) - : ( - - {intl.formatMessage(intlMessages.profileNotFoundLabel)} - - ) - } - - ) - } - {shouldShowVirtualBackgrounds && this.renderVirtualBgSelector()} - - } + ); + })} + + ) + : ( + + {intl.formatMessage(intlMessages.profileNotFoundLabel)} + + ) + } ); } - handleBrightnessAreaChange() { - const { wholeImageBrightness } = this.state; - this.currentVideoStream.toggleCameraBrightnessArea(!wholeImageBrightness); - this.setState({ wholeImageBrightness: !wholeImageBrightness }); + async handleBrightnessAreaChange() { + const ENABLE_CAMERA_BRIGHTNESS = window.meetingClientSettings.public.app.enableCameraBrightness; + const CAMERA_BRIGHTNESS_AVAILABLE = ENABLE_CAMERA_BRIGHTNESS && isVirtualBackgroundSupported(); + + if (CAMERA_BRIGHTNESS_AVAILABLE && this.currentVideoStream) { + if (this.currentVideoStream?.virtualBgService == null) { + await this.startCameraBrightness(); + } + + const { wholeImageBrightness } = this.state; + this.currentVideoStream.toggleCameraBrightnessArea(!wholeImageBrightness); + this.setState({ wholeImageBrightness: !wholeImageBrightness }); + } } renderBrightnessInput() { const { cameraAsContent, + cameraAsContentDeviceId, } = this.props; const { webcamDeviceId, } = this.state; + + const ENABLE_CAMERA_BRIGHTNESS = window.meetingClientSettings.public.app.enableCameraBrightness; + if (!ENABLE_CAMERA_BRIGHTNESS) return null; const { intl } = this.props; @@ -887,10 +1031,10 @@ class VideoPreview extends Component { ? (brightness * 100) / 200 : ((200 - brightness) * 100) / 200; - if(cameraAsContent){ return null } + if(cameraAsContent || webcamDeviceId === cameraAsContentDeviceId){ return null } return ( - <> + {intl.formatMessage(intlMessages.brightness)} @@ -914,8 +1058,7 @@ class VideoPreview extends Component { aria-describedby={'brightness-slider-desc'} onChange={(e) => { const brightness = e.target.valueAsNumber; - this.currentVideoStream.changeCameraBrightness(brightness); - this.setState({ brightness }); + this.setCameraBrightness(brightness); }} disabled={!isVirtualBackgroundSupported() || isStartSharingDisabled} /> @@ -938,30 +1081,60 @@ class VideoPreview extends Component { label={intl.formatMessage(intlMessages.wholeImageBrightnessLabel)} />
- + ); } renderVirtualBgSelector() { - const { isVisualEffects } = this.props; + const { isCustomVirtualBackgroundsEnabled } = this.props; const { isStartSharingDisabled, webcamDeviceId } = this.state; const initialVirtualBgState = this.currentVideoStream ? { type: this.currentVideoStream.virtualBgType, - name: this.currentVideoStream.virtualBgName - } : getSessionVirtualBackgroundInfo(webcamDeviceId); + name: this.currentVideoStream.virtualBgName, + uniqueId: this.currentVideoStream.virtualBgUniqueId, + } : getSessionVirtualBackgroundInfoWithDefault(webcamDeviceId); + const { + showThumbnails: SHOW_THUMBNAILS = true, + } = window.meetingClientSettings.public.virtualBackgrounds; + return ( ); } - renderContent() { + renderTabsContent(tabNumber) { + const { + cameraAsContent, + isVirtualBackgroundsEnabled, + } = this.props; + + const shouldShowVirtualBackgrounds = isVirtualBackgroundsEnabled && !cameraAsContent; + + return ( + + {tabNumber === 0 && ( + + {this.renderDeviceSelectors()} + {isVirtualBackgroundSupported() && this.renderBrightnessInput()} + + )} + {tabNumber === 1 && shouldShowVirtualBackgrounds && ( + + {this.renderVirtualBgSelector()} + + )} + + ); + } + + renderContent(selectedTab) { const { intl, } = this.props; @@ -972,14 +1145,23 @@ class VideoPreview extends Component { previewError, } = this.state; + const Settings = getSettingsSingletonInstance(); const { animations } = Settings.application; + const containerStyle = { + width: '60%', + height: '25vh', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + }; + switch (viewState) { case VIEW_STATES.finding: return ( -
+
{intl.formatMessage(intlMessages.findingWebcamsLabel)}
@@ -1015,10 +1197,7 @@ class VideoPreview extends Component { ) } - - {this.renderDeviceSelectors()} - {this.renderBrightnessInput()} - + {this.renderTabsContent(selectedTab)} ); } @@ -1030,13 +1209,13 @@ class VideoPreview extends Component { return intl.formatMessage(intlMessages.webcamSettingsTitle); } - renderModalContent() { + renderModalContent(selectedTab) { const { intl, hasVideoStream, forceOpen, camCapReached, - isVisualEffects, + closeModal, } = this.props; const { @@ -1045,12 +1224,13 @@ class VideoPreview extends Component { deviceError, previewError, } = this.state; - const shouldDisableButtons = PreviewService.getSkipVideoPreview() - && !forceOpen - && !(deviceError || previewError); + const shouldDisableButtons = this.shouldSkipVideoPreview() + && !(deviceError || previewError); const shared = this.isAlreadyShared(webcamDeviceId); + const showStopAllButton = hasVideoStream && VideoService.isMultipleCamerasEnabled(); + const { isIe } = browserInfo; return ( @@ -1068,56 +1248,80 @@ class VideoPreview extends Component { ) : null} - {this.renderContent()} + {this.renderContent(selectedTab)} - {!isVisualEffects ? ( - - {hasVideoStream && VideoService.isMultipleCamerasEnabled() - ? ( + + + + {showStopAllButton ? ( -
); - } + }; const handleCustomBgChange = (event) => { const file = event.target.files[0]; const onSuccess = (background) => { dispatch({ - type: 'new', + type: ACTIONS.NEW, background: { ...background, custom: true, @@ -252,33 +266,30 @@ const VirtualBgSelector = ({ const renderThumbnailSelector = () => { const disabled = locked || !isVirtualBackgroundSupported(); - const isRTL = Settings.application.isRTL; + const Settings = getSettingsSingletonInstance(); + const { isRTL } = Settings.application; - const renderBlurButton = (index) => { - return ( - - { inputElementsRef.current[index] = ref; }} - onClick={() => _virtualBgSelected(EFFECT_TYPES.BLUR_TYPE, 'Blur', index)} - isVisualEffects={isVisualEffects} - /> -
- {intl.formatMessage(intlMessages.camBgAriaDesc, { 0: EFFECT_TYPES.BLUR_TYPE })} -
-
- ); - }; + const renderBlurButton = (index) => ( + + { inputElementsRef.current[index] = ref; }} + onClick={() => _virtualBgSelected(EFFECT_TYPES.BLUR_TYPE, 'Blur', index)} + /> +
+ {intl.formatMessage(intlMessages.camBgAriaDesc, { 0: EFFECT_TYPES.BLUR_TYPE })} +
+
+ ); const renderDefaultButton = (imageName, index) => { const label = intl.formatMessage(intlMessages[imageName.split('.').shift()], { @@ -289,7 +300,6 @@ const VirtualBgSelector = ({ return ( inputElementsRef.current[index] = ref} + ref={(ref) => { inputElementsRef.current[index] = ref; }} onClick={() => _virtualBgSelected(EFFECT_TYPES.IMAGE_TYPE, imageName, index)} disabled={disabled} - isVisualEffects={isVisualEffects} background={getVirtualBackgroundThumbnail(imageName)} data-test="selectDefaultBackground" /> @@ -311,7 +320,7 @@ const VirtualBgSelector = ({ {intl.formatMessage(intlMessages.camBgAriaDesc, { 0: label })}
- ) + ); }; const renderCustomButton = (background, index) => { @@ -323,7 +332,6 @@ const VirtualBgSelector = ({ return ( inputElementsRef.current[index] = ref} + ref={(ref) => { inputElementsRef.current[index] = ref; }} onClick={() => _virtualBgSelected( EFFECT_TYPES.IMAGE_TYPE, filename, @@ -342,7 +350,6 @@ const VirtualBgSelector = ({ { file: data, uniqueId }, )} disabled={disabled} - isVisualEffects={isVisualEffects} background={data} data-test="selectCustomBackground" /> @@ -360,7 +367,7 @@ const VirtualBgSelector = ({ hideLabel onClick={() => { dispatch({ - type: 'delete', + type: ACTIONS.DELETE, uniqueId, }); _virtualBgSelected(EFFECT_TYPES.NONE_TYPE); @@ -377,9 +384,9 @@ const VirtualBgSelector = ({ const renderInputButton = () => ( <> -
+
{intl.formatMessage(intlMessages.customDesc)}
@@ -408,18 +414,17 @@ const VirtualBgSelector = ({ const renderNoneButton = () => ( <> _virtualBgSelected(EFFECT_TYPES.NONE_TYPE)} - isVisualEffects={isVisualEffects} data-test="noneBackgroundButton" /> -
+
{intl.formatMessage(intlMessages.camBgAriaDesc, { 0: EFFECT_TYPES.NONE_TYPE })}
@@ -428,6 +433,7 @@ const VirtualBgSelector = ({ const renderSkeleton = () => ( {new Array(SKELETON_COUNT).fill(null).map((_, index) => ( + // eslint-disable-next-line react/no-array-index-key @@ -436,17 +442,17 @@ const VirtualBgSelector = ({ ); const ready = loaded && defaultSetUp; + const ENABLE_CAMERA_BRIGHTNESS = window.meetingClientSettings.public.app.enableCameraBrightness; return ( - {shouldEnableBackgroundUpload() && ( + {shouldEnableBackgroundUpload(isCustomVirtualBackgroundsEnabled) && ( <> {!ready && renderSkeleton()} @@ -459,10 +465,11 @@ const VirtualBgSelector = ({ .map((background, index) => { if (background.custom !== false) { return renderCustomButton(background, index); - } else { - const isBlur = background.uniqueId.includes('Blur'); - return isBlur ? renderBlurButton(index) : renderDefaultButton(background.uniqueId, index); } + const isBlur = background.uniqueId.includes('Blur'); + return isBlur + ? renderBlurButton(index) + : renderDefaultButton(background.uniqueId, index); })} {renderInputButton()} @@ -471,7 +478,7 @@ const VirtualBgSelector = ({ )} - {!shouldEnableBackgroundUpload() && ( + {!shouldEnableBackgroundUpload(isCustomVirtualBackgroundsEnabled) && ( <> {renderNoneButton()} @@ -495,13 +502,13 @@ const VirtualBgSelector = ({ return ( <> - {!isVisualEffects && ( - - {!isVirtualBackgroundSupported() - ? intl.formatMessage(intlMessages.virtualBackgroundSettingsDisabledLabel) - : intl.formatMessage(intlMessages.virtualBackgroundSettingsLabel)} - - )} + + {intl.formatMessage( + isVirtualBackgroundSupported() + ? intlMessages.virtualBackgroundSettingsLabel + : intlMessages.virtualBackgroundSettingsDisabledLabel, + )} + {renderSelector()} @@ -509,11 +516,5 @@ const VirtualBgSelector = ({ }; VirtualBgSelector.propTypes = propTypes; -VirtualBgSelector.defaultProps = { - showThumbnails: false, - initialVirtualBgState: { - type: EFFECT_TYPES.NONE_TYPE, - }, -}; export default injectIntl(withFileReader(VirtualBgSelector, MIME_TYPES_ALLOWED, MAX_FILE_SIZE)); diff --git a/bigbluebutton-html5/imports/ui/components/video-preview/virtual-background/context.jsx b/bigbluebutton-html5/imports/ui/components/video-preview/virtual-background/context.jsx index 05e14a62bf..26b8515a2e 100644 --- a/bigbluebutton-html5/imports/ui/components/video-preview/virtual-background/context.jsx +++ b/bigbluebutton-html5/imports/ui/components/video-preview/virtual-background/context.jsx @@ -1,14 +1,26 @@ -import React, { useReducer } from 'react'; +import React, { useEffect, useReducer } from 'react'; +import { v4 as uuid } from 'uuid'; import { throttle } from '/imports/utils/throttle'; import Service from './service'; +import useCurrentUser from '/imports/ui/core/hooks/useCurrentUser'; +import logger from '/imports/startup/client/logger'; +import { EFFECT_TYPES } from '/imports/ui/services/virtual-background/service'; export const CustomVirtualBackgroundsContext = React.createContext(); +export const ACTIONS = { + LOAD: 'load', + NEW: 'new', + DELETE: 'delete', + UPDATE: 'update', + SET_DEFAULT: 'setDefault', +}; + const reducer = (state, action) => { const { save, del, update } = Service; switch (action.type) { - case 'load': { + case ACTIONS.LOAD: { const backgrounds = { ...state.backgrounds }; action.backgrounds.forEach((background) => { backgrounds[background.uniqueId] = background; @@ -19,17 +31,20 @@ const reducer = (state, action) => { backgrounds, }; } - case 'new': { - save(action.background); + case ACTIONS.NEW: { + const { backgrounds } = state; + const { background } = action; + const { uniqueId = uuid() } = background; + if (background.custom && !background.sessionOnly) save(background); return { ...state, backgrounds: { - ...state.backgrounds, - [action.background.uniqueId]: action.background, + ...backgrounds, + [uniqueId]: background, }, }; } - case 'delete': { + case ACTIONS.DELETE: { const { backgrounds } = state; delete backgrounds[action.uniqueId]; del(action.uniqueId); @@ -38,17 +53,25 @@ const reducer = (state, action) => { backgrounds, }; } - case 'update': { - if (action.background.custom) update(action.background); + case ACTIONS.UPDATE: { + const { backgrounds } = state; + const { background } = action; + const { uniqueId } = background; + if (!uniqueId) return state; + const updatedBackground = { + ...(backgrounds[uniqueId] || {}), + ...background, + }; + if (updatedBackground.custom && !updatedBackground.sessionOnly) update(updatedBackground); return { ...state, backgrounds: { - ...state.backgrounds, - [action.background.uniqueId]: action.background, + ...backgrounds, + [uniqueId]: updatedBackground, }, }; } - case 'setDefault': { + case ACTIONS.SET_DEFAULT: { const backgrounds = { ...state.backgrounds }; action.backgrounds.forEach((background) => { backgrounds[background.uniqueId] = background; @@ -71,23 +94,58 @@ export const CustomBackgroundsProvider = ({ children }) => { defaultSetUp: false, backgrounds: {}, }); + const { data: currentUser, loading: isCurrentUserLoading } = useCurrentUser((u) => ({ + webcamBackground: u.webcamBackground, + })); const { load } = Service; const loadFromDB = () => { const onError = () => dispatch({ - type: 'load', + type: ACTIONS.LOAD, backgrounds: [], }); const onSuccess = (backgrounds) => dispatch({ - type: 'load', + type: ACTIONS.LOAD, backgrounds, }); load(onError, onSuccess); }; + useEffect(() => { + if (!isCurrentUserLoading && currentUser && !state.backgrounds.webcamBackgroundURL) { + const webcamBackgroundURL = currentUser.webcamBackground; + if (webcamBackgroundURL !== '' && !state.backgrounds.webcamBackgroundURL) { + Service.getFileFromUrl(webcamBackgroundURL) + .then((fetchedWebcamBackground) => { + if (fetchedWebcamBackground) { + const data = URL.createObjectURL(fetchedWebcamBackground); + const uniqueId = 'webcamBackgroundURL'; + const filename = webcamBackgroundURL; + dispatch({ + type: ACTIONS.UPDATE, + background: { + filename, + uniqueId, + data, + lastActivityDate: Date.now(), + custom: true, + sessionOnly: true, + type: EFFECT_TYPES.IMAGE_TYPE, + }, + }); + } else { + logger.error({ + logCode: 'webcam_background_fetch_error', + }, 'Failed to fetch custom webcam background image.'); + } + }); + } + } + }, [isCurrentUserLoading, currentUser]); + return ( { }); }; +// Function to convert image URL to a File object +async function getFileFromUrl(url) { + try { + const response = await fetch(url, { + credentials: 'omit', + mode: 'cors', + headers: { + Accept: 'image/*', + }, + }); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const blob = await response.blob(); + const file = new File([blob], 'fetchedWebcamBackground', { type: blob.type }); + return file; + } catch (error) { + logger.error({ + logCode: 'image_fetch_error', + extraInfo: { + errorMessage: error?.message, + errorName: error?.name, + errorStack: error?.stack, + }, + }, `Fetching image from ${url} failed.`); + return null; + } +} + export default { load, save, @@ -111,4 +140,5 @@ export default { update, MIME_TYPES_ALLOWED, MAX_FILE_SIZE, + getFileFromUrl, }; diff --git a/bigbluebutton-html5/imports/ui/components/video-preview/virtual-background/styles.js b/bigbluebutton-html5/imports/ui/components/video-preview/virtual-background/styles.js index ec2db6c2b4..b04a9d08f0 100644 --- a/bigbluebutton-html5/imports/ui/components/video-preview/virtual-background/styles.js +++ b/bigbluebutton-html5/imports/ui/components/video-preview/virtual-background/styles.js @@ -16,28 +16,27 @@ import { } from '/imports/ui/stylesheets/styled-components/palette'; import { ScrollboxVertical } from '/imports/ui/stylesheets/styled-components/scrollable'; import { fontSizeSmallest } from '/imports/ui/stylesheets/styled-components/typography'; +import { smallOnly, mediumOnly } from '/imports/ui/stylesheets/styled-components/breakpoints'; import Button from '/imports/ui/components/common/button/component'; const VirtualBackgroundRowThumbnail = styled.div` - margin-top: 0.4rem; + margin: 0.4rem; `; const BgWrapper = styled(ScrollboxVertical)` display: flex; justify-content: flex-start; - overflow-x: auto; + max-width: 272px; + max-height: 216px; + flex-wrap: wrap; + overflow-y: auto; margin: ${borderSizeLarge}; padding: ${borderSizeLarge}; - ${({ isVisualEffects }) => isVisualEffects && ` - height: 15rem; - flex-wrap: wrap; - align-content: flex-start; - `} - - ${({ brightnessEnabled, isVisualEffects }) => brightnessEnabled && isVisualEffects && ` - height: 10rem; - `} + @media ${smallOnly}, ${mediumOnly} { + justify-content: center; + max-height: 22vh; + } `; const BgNoneButton = styled(Button)` @@ -45,12 +44,8 @@ const BgNoneButton = styled(Button)` height: 48px; width: 48px; border: ${borderSizeSmall} solid ${userThumbnailBorder}; - margin: 0 0.15rem; + margin: 0.5rem 0.5rem; flex-shrink: 0; - - ${({ isVisualEffects }) => isVisualEffects && ` - margin: 0.15rem; - `} `; const ThumbnailButton = styled(Button)` @@ -89,8 +84,9 @@ const ThumbnailButton = styled(Button)` ${({ background }) => background && ` background-image: url(${background}); - background-size: 46px 46px; background-origin: padding-box; + background-size: cover; + background-position: center; &:active { background-image: url(${background}); @@ -131,11 +127,7 @@ const Label = styled.label` const ThumbnailButtonWrapper = styled.div` position: relative; - margin: 0 0.15rem; - - ${({ isVisualEffects }) => isVisualEffects && ` - margin: 0.15rem; - `} + margin: 0.5rem 0.5rem; `; const ButtonWrapper = styled.div` @@ -177,4 +169,4 @@ export default { ButtonRemove, BgCustomButton, SkeletonWrapper, -}; \ No newline at end of file +}; diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx b/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx deleted file mode 100755 index e7d5783006..0000000000 --- a/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx +++ /dev/null @@ -1,1291 +0,0 @@ -/* eslint react/sort-comp: 0 */ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import ReconnectingWebSocket from 'reconnecting-websocket'; -import { defineMessages, injectIntl } from 'react-intl'; -import { debounce } from '/imports/utils/debounce'; -import VideoService from './service'; -import VideoListContainer from './video-list/container'; -import { - fetchWebRTCMappedStunTurnServers, - getMappedFallbackStun, -} from '/imports/utils/fetchStunTurnServers'; -import logger from '/imports/startup/client/logger'; -import { notifyStreamStateChange } from '/imports/ui/services/bbb-webrtc-sfu/stream-state-service'; -import VideoPreviewService from '../video-preview/service'; -import MediaStreamUtils from '/imports/utils/media-stream-utils'; -import BBBVideoStream from '/imports/ui/services/webrtc-base/bbb-video-stream'; -import { - EFFECT_TYPES, - getSessionVirtualBackgroundInfo, -} from '/imports/ui/services/virtual-background/service'; -import { notify } from '/imports/ui/services/notification'; -import { shouldForceRelay } from '/imports/ui/services/bbb-webrtc-sfu/utils'; -import WebRtcPeer from '/imports/ui/services/webrtc-base/peer'; - -// Default values and default empty object to be backwards compat with 2.2. -// FIXME Remove hardcoded defaults 2.3. -const { - connectionTimeout: WS_CONN_TIMEOUT = 4000, - maxRetries: WS_MAX_RETRIES = 5, - debug: WS_DEBUG, - heartbeat: WS_HEARTBEAT_OPTS = { - interval: 15000, - delay: 3000, - reconnectOnFailure: true, - }, -} = window.meetingClientSettings.public.kurento.cameraWsOptions; - -const { webcam: NETWORK_PRIORITY } = window.meetingClientSettings.public.media.networkPriorities || {}; -const { - baseTimeout: CAMERA_SHARE_FAILED_WAIT_TIME = 15000, - maxTimeout: MAX_CAMERA_SHARE_FAILED_WAIT_TIME = 60000, -} = window.meetingClientSettings.public.kurento.cameraTimeouts || {}; -const { - enabled: CAMERA_QUALITY_THRESHOLDS_ENABLED = true, - privilegedStreams: CAMERA_QUALITY_THR_PRIVILEGED = true, -} = window.meetingClientSettings.public.kurento.cameraQualityThresholds; -const SIGNAL_CANDIDATES = window.meetingClientSettings.public.kurento.signalCandidates; -const TRACE_LOGS = window.meetingClientSettings.public.kurento.traceLogs; -const GATHERING_TIMEOUT = window.meetingClientSettings.public.kurento.gatheringTimeout; - -const intlClientErrors = defineMessages({ - permissionError: { - id: 'app.video.permissionError', - description: 'Webcam permission error', - }, - iceConnectionStateError: { - id: 'app.video.iceConnectionStateError', - description: 'Ice connection state failed', - }, - mediaFlowTimeout: { - id: 'app.video.mediaFlowTimeout1020', - description: 'Media flow timeout', - }, - mediaTimedOutError: { - id: 'app.video.mediaTimedOutError', - description: 'Media was ejected by the server due to lack of valid media', - }, - virtualBgGenericError: { - id: 'app.video.virtualBackground.genericError', - description: 'Failed to apply camera effect', - }, - inactiveError: { - id: 'app.video.inactiveError', - description: 'Camera stopped unexpectedly', - }, -}); - -const intlSFUErrors = defineMessages({ - 2000: { - id: 'app.sfu.mediaServerConnectionError2000', - description: 'SFU connection to the media server', - }, - 2001: { - id: 'app.sfu.mediaServerOffline2001', - description: 'SFU is offline', - }, - 2002: { - id: 'app.sfu.mediaServerNoResources2002', - description: 'Media server lacks disk, CPU or FDs', - }, - 2003: { - id: 'app.sfu.mediaServerRequestTimeout2003', - description: 'Media requests timeout due to lack of resources', - }, - 2021: { - id: 'app.sfu.serverIceGatheringFailed2021', - description: 'Server cannot enact ICE gathering', - }, - 2022: { - id: 'app.sfu.serverIceStateFailed2022', - description: 'Server endpoint transitioned to a FAILED ICE state', - }, - 2200: { - id: 'app.sfu.mediaGenericError2200', - description: 'SFU component generated a generic error', - }, - 2202: { - id: 'app.sfu.invalidSdp2202', - description: 'Client provided an invalid SDP', - }, - 2203: { - id: 'app.sfu.noAvailableCodec2203', - description: 'Server has no available codec for the client', - }, -}); - -const propTypes = { - streams: PropTypes.arrayOf(Array).isRequired, - intl: PropTypes.objectOf(Object).isRequired, - isUserLocked: PropTypes.bool.isRequired, - swapLayout: PropTypes.bool.isRequired, - currentVideoPageIndex: PropTypes.number.isRequired, - totalNumberOfStreams: PropTypes.number.isRequired, - isMeteorConnected: PropTypes.bool.isRequired, - playStart: PropTypes.func.isRequired, - sendUserUnshareWebcam: PropTypes.func.isRequired, -}; - -class VideoProvider extends Component { - onBeforeUnload() { - const { sendUserUnshareWebcam } = this.props; - VideoService.onBeforeUnload(sendUserUnshareWebcam); - } - - static shouldAttachVideoStream(peer, videoElement) { - // Conditions to safely attach a stream to a video element in all browsers: - // 1 - Peer exists, video element exists - // 2 - Target stream differs from videoElement's (diff) - // 3a - If the stream is a remote one, the safest (*ahem* Safari) moment to - // do so is waiting for the server to confirm that media has flown out of it - // towards te remote end (peer.started) - // 3b - If the stream is a local one (webcam sharer) and is started - // 4 - If the stream is local one, check if there area video tracks there are - // video tracks: attach it - if (peer == null || videoElement == null) return false; - const stream = peer.isPublisher ? peer.getLocalStream() : peer.getRemoteStream(); - const diff = stream && (stream.id !== videoElement.srcObject?.id || !videoElement.paused); - - if (peer.started && diff) return true; - - return peer.isPublisher - && peer.getLocalStream() - && peer.getLocalStream().getVideoTracks().length > 0 - && diff; - } - - constructor(props) { - super(props); - - // socketOpen state is there to force update when the signaling socket opens or closes - this.state = { - socketOpen: false, - }; - this._isMounted = false; - this.info = VideoService.getInfo(); - // Signaling message queue arrays indexed by stream (== cameraId) - this.wsQueues = {}; - this.restartTimeout = {}; - this.restartTimer = {}; - this.webRtcPeers = {}; - this.outboundIceQueues = {}; - this.videoTags = {}; - - this.createVideoTag = this.createVideoTag.bind(this); - this.destroyVideoTag = this.destroyVideoTag.bind(this); - this.onWsOpen = this.onWsOpen.bind(this); - this.onWsClose = this.onWsClose.bind(this); - this.onWsMessage = this.onWsMessage.bind(this); - this.updateStreams = this.updateStreams.bind(this); - this.connectStreams = this.connectStreams.bind(this); - this.debouncedConnectStreams = debounce( - this.connectStreams, - VideoService.getPageChangeDebounceTime(), - { leading: false, trailing: true }, - ); - this.startVirtualBackgroundByDrop = this.startVirtualBackgroundByDrop.bind(this); - this.onBeforeUnload = this.onBeforeUnload.bind(this); - } - - componentDidMount() { - this._isMounted = true; - VideoService.updatePeerDictionaryReference(this.webRtcPeers); - this.ws = this.openWs(); - window.addEventListener('beforeunload', this.onBeforeUnload); - } - - componentDidUpdate(prevProps) { - const { - isUserLocked, - streams, - currentVideoPageIndex, - isMeteorConnected, - sendUserUnshareWebcam, - } = this.props; - const { socketOpen } = this.state; - - // Only debounce when page changes to avoid unnecessary debouncing - const shouldDebounce = VideoService.isPaginationEnabled() - && prevProps.currentVideoPageIndex !== currentVideoPageIndex; - - if (isMeteorConnected && socketOpen) this.updateStreams(streams, shouldDebounce); - if (!prevProps.isUserLocked && isUserLocked) VideoService.lockUser(sendUserUnshareWebcam); - - // Signaling socket expired its retries and meteor is connected - create - // a new signaling socket instance from scratch - if (!socketOpen - && isMeteorConnected - && this.ws == null) { - this.ws = this.openWs(); - } - } - - componentWillUnmount() { - const { sendUserUnshareWebcam } = this.props; - this._isMounted = false; - VideoService.updatePeerDictionaryReference({}); - - if (this.ws) { - this.ws.onmessage = null; - this.ws.onopen = null; - this.ws.onclose = null; - } - - window.removeEventListener('beforeunload', this.onBeforeUnload); - VideoService.exitVideo(sendUserUnshareWebcam); - Object.keys(this.webRtcPeers).forEach((stream) => { - this.stopWebRTCPeer(stream, false); - }); - this.terminateWs(); - } - - openWs() { - const ws = new ReconnectingWebSocket( - VideoService.getAuthenticatedURL(), [], { - connectionTimeout: WS_CONN_TIMEOUT, - debug: WS_DEBUG, - maxRetries: WS_MAX_RETRIES, - maxEnqueuedMessages: 0, - } - ); - ws.onopen = this.onWsOpen; - ws.onclose = this.onWsClose; - ws.onmessage = this.onWsMessage; - - return ws; - } - - terminateWs() { - if (this.ws) { - this.clearWSHeartbeat(); - this.ws.close(); - this.ws = null; - } - } - - _updateLastMsgTime() { - this.ws.isAlive = true; - this.ws.lastMsgTime = Date.now(); - } - - _getTimeSinceLastMsg() { - return Date.now() - this.ws.lastMsgTime; - } - - setupWSHeartbeat() { - if (WS_HEARTBEAT_OPTS.interval === 0 || this.ws == null || this.ws.wsHeartbeat) return; - - this.ws.isAlive = true; - this.ws.wsHeartbeat = setInterval(() => { - if (this.ws.isAlive === false) { - logger.warn({ - logCode: 'video_provider_ws_heartbeat_failed', - }, 'Video provider WS heartbeat failed.'); - - if (WS_HEARTBEAT_OPTS.reconnectOnFailure) this.ws.reconnect(); - return; - } - - if (this._getTimeSinceLastMsg() < ( - WS_HEARTBEAT_OPTS.interval - WS_HEARTBEAT_OPTS.delay - )) { - return; - } - - this.ws.isAlive = false; - this.ping(); - }, WS_HEARTBEAT_OPTS.interval); - - this.ping(); - } - - clearWSHeartbeat() { - if (this.ws?.wsHeartbeat) { - clearInterval(this.ws.wsHeartbeat); - this.ws.wsHeartbeat = null; - } - } - - onWsMessage(message) { - this._updateLastMsgTime(); - const parsedMessage = JSON.parse(message.data); - - if (parsedMessage.id === 'pong') return; - - switch (parsedMessage.id) { - case 'startResponse': - this.startResponse(parsedMessage); - break; - - case 'playStart': - this.handlePlayStart(parsedMessage); - break; - - case 'playStop': - this.handlePlayStop(parsedMessage); - break; - - case 'iceCandidate': - this.handleIceCandidate(parsedMessage); - break; - - case 'pong': - break; - - case 'error': - default: - this.handleSFUError(parsedMessage); - break; - } - } - - onWsClose() { - const { sendUserUnshareWebcam } = this.props; - logger.info({ - logCode: 'video_provider_onwsclose', - }, 'Multiple video provider websocket connection closed.'); - - this.clearWSHeartbeat(); - VideoService.exitVideo(sendUserUnshareWebcam); - // Media is currently tied to signaling state - so if signaling shuts down, - // media will shut down server-side. This cleans up our local state faster - // and notify the state change as failed so the UI rolls back to the placeholder - // avatar UI in the camera container - Object.keys(this.webRtcPeers).forEach((stream) => { - if (this.stopWebRTCPeer(stream, false)) { - notifyStreamStateChange(stream, 'failed'); - } - }); - this.setState({ socketOpen: false }); - - if (this.ws && this.ws.retryCount >= WS_MAX_RETRIES) { - this.terminateWs(); - } - } - - onWsOpen() { - logger.info({ - logCode: 'video_provider_onwsopen', - }, 'Multiple video provider websocket connection opened.'); - - this._updateLastMsgTime(); - this.setupWSHeartbeat(); - this.setState({ socketOpen: true }); - // Resend queued messages that happened when socket was not connected - Object.entries(this.wsQueues).forEach(([stream, queue]) => { - if (this.webRtcPeers[stream]) { - // Peer - send enqueued - while (queue.length > 0) { - this.sendMessage(queue.pop()); - } - } else { - // No peer - delete queue - this.wsQueues[stream] = null; - } - }); - } - - findAllPrivilegedStreams () { - const { streams } = this.props; - // Privileged streams are: floor holders, pinned users - return streams.filter(stream => stream.floor || stream.pin); - } - - updateQualityThresholds(numberOfPublishers) { - const { threshold, profile } = VideoService.getThreshold(numberOfPublishers); - if (profile) { - const privilegedStreams = this.findAllPrivilegedStreams(); - Object.values(this.webRtcPeers) - .filter(peer => peer.isPublisher) - .forEach((peer) => { - // Conditions which make camera revert their original profile - // 1) Threshold 0 means original profile/inactive constraint - // 2) Privileged streams - const exempt = threshold === 0 - || (CAMERA_QUALITY_THR_PRIVILEGED && privilegedStreams.some(vs => vs.stream === peer.stream)) - const profileToApply = exempt ? peer.originalProfileId : profile; - VideoService.applyCameraProfile(peer, profileToApply); - }); - } - } - - getStreamsToConnectAndDisconnect(streams) { - const streamsCameraIds = streams.filter(s => !s?.isGridItem).map(s => s.stream); - const streamsConnected = Object.keys(this.webRtcPeers); - - const streamsToConnect = streamsCameraIds.filter(stream => { - return !streamsConnected.includes(stream); - }); - - const streamsToDisconnect = streamsConnected.filter(stream => { - return !streamsCameraIds.includes(stream); - }); - - return [streamsToConnect, streamsToDisconnect]; - } - - connectStreams(streamsToConnect) { - streamsToConnect.forEach((stream) => { - const isLocal = VideoService.isLocalStream(stream); - this.createWebRTCPeer(stream, isLocal); - }); - } - - disconnectStreams(streamsToDisconnect) { - streamsToDisconnect.forEach(stream => this.stopWebRTCPeer(stream, false)); - } - - updateStreams(streams, shouldDebounce = false) { - const [streamsToConnect, streamsToDisconnect] = this.getStreamsToConnectAndDisconnect(streams); - - if (shouldDebounce) { - this.debouncedConnectStreams(streamsToConnect); - } else { - this.connectStreams(streamsToConnect); - } - - this.disconnectStreams(streamsToDisconnect); - - if (CAMERA_QUALITY_THRESHOLDS_ENABLED) { - this.updateQualityThresholds(this.props.totalNumberOfStreams); - } - } - - ping() { - const message = { id: 'ping' }; - this.sendMessage(message); - } - - sendMessage(message) { - const { ws } = this; - - if (this.connectedToMediaServer()) { - const jsonMessage = JSON.stringify(message); - try { - ws.send(jsonMessage); - } catch (error) { - logger.error({ - logCode: 'video_provider_ws_send_error', - extraInfo: { - errorMessage: error.message || 'Unknown', - errorCode: error.code, - }, - }, 'Camera request failed to be sent to SFU'); - } - } else if (message.id !== 'stop') { - // No need to queue video stop messages - const { cameraId } = message; - if (cameraId) { - if (this.wsQueues[cameraId] == null) this.wsQueues[cameraId] = []; - this.wsQueues[cameraId].push(message); - } - } - } - - connectedToMediaServer() { - return this.ws && this.ws.readyState === ReconnectingWebSocket.OPEN; - } - - processOutboundIceQueue(peer, role, stream) { - const queue = this.outboundIceQueues[stream]; - while (queue && queue.length) { - const candidate = queue.shift(); - this.sendIceCandidateToSFU(peer, role, candidate, stream); - } - } - - sendLocalAnswer (peer, stream, answer) { - const message = { - id: 'subscriberAnswer', - type: 'video', - role: VideoService.getRole(peer.isPublisher), - cameraId: stream, - answer, - }; - - this.sendMessage(message); - } - - startResponse(message) { - const { cameraId: stream, role } = message; - const peer = this.webRtcPeers[stream]; - - logger.debug({ - logCode: 'video_provider_start_response_success', - extraInfo: { cameraId: stream, role }, - }, `Camera start request accepted by SFU. Role: ${role}`); - - if (peer) { - const processorFunc = peer.isPublisher - ? peer.processAnswer.bind(peer) - : peer.processOffer.bind(peer); - - processorFunc(message.sdpAnswer).then((answer) => { - if (answer) this.sendLocalAnswer(peer, stream, answer); - - peer.didSDPAnswered = true; - this.processOutboundIceQueue(peer, role, stream); - VideoService.processInboundIceQueue(peer, stream); - }).catch((error) => { - logger.error({ - logCode: 'video_provider_peerconnection_process_error', - extraInfo: { - cameraId: stream, - role, - errorMessage: error.message, - errorCode: error.code, - }, - }, 'Camera answer processing failed'); - }); - } else { - logger.warn({ - logCode: 'video_provider_startresponse_no_peer', - extraInfo: { cameraId: stream, role }, - }, 'No peer on SFU camera start response handler'); - } - } - - handleIceCandidate(message) { - const { cameraId: stream, candidate } = message; - const peer = this.webRtcPeers[stream]; - - if (peer) { - if (peer.didSDPAnswered) { - VideoService.addCandidateToPeer(peer, candidate, stream); - } else { - // ICE candidates are queued until a SDP answer has been processed. - // This was done due to a long term iOS/Safari quirk where it'd - // fail if candidates were added before the offer/answer cycle was completed. - // Dunno if that still happens, but it works even if it slows the ICE checks - // a bit - prlanzarin july 2019 - if (peer.inboundIceQueue == null) { - peer.inboundIceQueue = []; - } - peer.inboundIceQueue.push(candidate); - } - } else { - logger.warn({ - logCode: 'video_provider_addicecandidate_no_peer', - extraInfo: { cameraId: stream }, - }, 'Trailing camera ICE candidate, discarded'); - } - } - - clearRestartTimers(stream) { - if (this.restartTimeout[stream]) { - clearTimeout(this.restartTimeout[stream]); - delete this.restartTimeout[stream]; - } - - if (this.restartTimer[stream]) { - delete this.restartTimer[stream]; - } - } - - stopWebRTCPeer(stream, restarting = false) { - const isLocal = VideoService.isLocalStream(stream); - const { sendUserUnshareWebcam } = this.props; - - // in this case, 'closed' state is not caused by an error; - // we stop listening to prevent this from being treated as an error - const peer = this.webRtcPeers[stream]; - if (peer && peer.peerConnection) { - const conn = peer.peerConnection; - conn.oniceconnectionstatechange = null; - } - - if (isLocal) { - VideoService.stopVideo(stream, sendUserUnshareWebcam); - } - - const role = VideoService.getRole(isLocal); - - logger.info({ - logCode: 'video_provider_stopping_webcam_sfu', - extraInfo: { role, cameraId: stream, restarting }, - }, `Camera feed stop requested. Role ${role}, restarting ${restarting}`); - - this.sendMessage({ - id: 'stop', - type: 'video', - cameraId: stream, - role, - }); - - // Clear the shared camera media flow timeout and current reconnect period - // when destroying it if the peer won't restart - if (!restarting) { - this.clearRestartTimers(stream); - } - - return this.destroyWebRTCPeer(stream); - } - - destroyWebRTCPeer(stream) { - let stopped = false; - const peer = this.webRtcPeers[stream]; - const isLocal = VideoService.isLocalStream(stream); - const role = VideoService.getRole(isLocal); - - if (peer) { - if (peer && peer.bbbVideoStream) { - if (typeof peer.inactivationHandler === 'function') { - peer.bbbVideoStream.removeListener('inactive', peer.inactivationHandler); - } - peer.bbbVideoStream.stop(); - } - - if (typeof peer.dispose === 'function') { - peer.dispose(); - } - - delete this.webRtcPeers[stream]; - stopped = true; - } else { - logger.warn({ - logCode: 'video_provider_destroywebrtcpeer_no_peer', - extraInfo: { cameraId: stream, role }, - }, 'Trailing camera destroy request.'); - } - - delete this.outboundIceQueues[stream]; - delete this.wsQueues[stream]; - - return stopped; - } - - _createPublisher(stream, peerOptions) { - return new Promise((resolve, reject) => { - try { - const { id: profileId } = VideoService.getCameraProfile(); - let bbbVideoStream = VideoService.getPreloadedStream(); - - if (bbbVideoStream) { - peerOptions.videoStream = bbbVideoStream.mediaStream; - } - - const peer = new WebRtcPeer('sendonly', peerOptions); - peer.bbbVideoStream = bbbVideoStream; - this.webRtcPeers[stream] = peer; - peer.stream = stream; - peer.started = false; - peer.didSDPAnswered = false; - peer.inboundIceQueue = []; - peer.isPublisher = true; - peer.originalProfileId = profileId; - peer.currentProfileId = profileId; - peer.start(); - peer.generateOffer().then((offer) => { - // Store the media stream if necessary. The scenario here is one where - // there is no preloaded stream stored. - if (peer.bbbVideoStream == null) { - bbbVideoStream = new BBBVideoStream(peer.getLocalStream()); - VideoPreviewService.storeStream( - MediaStreamUtils.extractDeviceIdFromStream( - bbbVideoStream.mediaStream, - 'video', - ), - bbbVideoStream, - ); - } - - peer.bbbVideoStream = bbbVideoStream; - bbbVideoStream.on('streamSwapped', ({ newStream }) => { - if (newStream && newStream instanceof MediaStream) { - this.replacePCVideoTracks(stream, newStream); - } - }); - peer.inactivationHandler = () => this._handleLocalStreamInactive(stream); - bbbVideoStream.once('inactive', peer.inactivationHandler); - resolve(offer); - }).catch(reject); - } catch (error) { - reject(error); - } - }); - } - - _createSubscriber(stream, peerOptions) { - return new Promise((resolve, reject) => { - try { - const peer = new WebRtcPeer('recvonly', peerOptions); - this.webRtcPeers[stream] = peer; - peer.stream = stream; - peer.started = false; - peer.didSDPAnswered = false; - peer.inboundIceQueue = []; - peer.isPublisher = false; - peer.start(); - resolve(); - } catch (error) { - reject(error); - } - }); - } - - async createWebRTCPeer(stream, isLocal) { - let iceServers = []; - const role = VideoService.getRole(isLocal); - const peerBuilderFunc = isLocal - ? this._createPublisher.bind(this) - : this._createSubscriber.bind(this); - - // Check if the peer is already being processed - if (this.webRtcPeers[stream]) { - return; - } - - this.webRtcPeers[stream] = {}; - this.outboundIceQueues[stream] = []; - const { constraints, bitrate } = VideoService.getCameraProfile(); - const peerOptions = { - mediaConstraints: { - audio: false, - video: constraints, - }, - onicecandidate: this._getOnIceCandidateCallback(stream, isLocal), - configuration: { - }, - trace: TRACE_LOGS, - networkPriorities: NETWORK_PRIORITY ? { video: NETWORK_PRIORITY } : undefined, - gatheringTimeout: GATHERING_TIMEOUT, - }; - - try { - iceServers = await fetchWebRTCMappedStunTurnServers(this.info.sessionToken); - } catch (error) { - logger.error({ - logCode: 'video_provider_fetchstunturninfo_error', - extraInfo: { - cameraId: stream, - role, - errorCode: error.code, - errorMessage: error.message, - }, - }, 'video-provider failed to fetch STUN/TURN info, using default'); - // Use fallback STUN server - iceServers = getMappedFallbackStun(); - } finally { - // we need to set iceTransportPolicy after `fetchWebRTCMappedStunTurnServers` - // because `shouldForceRelay` uses the information from the stun API - peerOptions.configuration.iceTransportPolicy = shouldForceRelay() ? 'relay' : undefined; - if (iceServers.length > 0) { - peerOptions.configuration.iceServers = iceServers; - } - - peerBuilderFunc(stream, peerOptions).then((offer) => { - if (!this._isMounted) { - return this.stopWebRTCPeer(stream, false); - } - const peer = this.webRtcPeers[stream]; - - if (peer && peer.peerConnection) { - const conn = peer.peerConnection; - conn.onconnectionstatechange = () => { - this._handleIceConnectionStateChange(stream, isLocal); - }; - } - - const message = { - id: 'start', - type: 'video', - cameraId: stream, - role, - sdpOffer: offer, - bitrate, - record: VideoService.getRecord(), - mediaServer: VideoService.getMediaServerAdapter(), - }; - - logger.info({ - logCode: 'video_provider_sfu_request_start_camera', - extraInfo: { - cameraId: stream, - role, - }, - }, `Camera offer generated. Role: ${role}`); - - this.setReconnectionTimeout(stream, isLocal, false); - this.sendMessage(message); - - return; - }).catch(error => { - return this._onWebRTCError(error, stream, isLocal); - }); - } - } - - _getWebRTCStartTimeout(stream, isLocal) { - const { intl } = this.props; - - return () => { - const role = VideoService.getRole(isLocal); - if (!isLocal) { - // Peer that timed out is a subscriber/viewer - // Subscribers try to reconnect according to their timers if media could - // not reach the server. That's why we pass the restarting flag as true - // to the stop procedure as to not destroy the timers - // Create new reconnect interval time - const oldReconnectTimer = this.restartTimer[stream]; - const newReconnectTimer = Math.min( - 2 * oldReconnectTimer, - MAX_CAMERA_SHARE_FAILED_WAIT_TIME, - ); - this.restartTimer[stream] = newReconnectTimer; - - // Clear the current reconnect interval so it can be re-set in createWebRTCPeer - if (this.restartTimeout[stream]) { - delete this.restartTimeout[stream]; - } - - logger.error({ - logCode: 'video_provider_camera_view_timeout', - extraInfo: { - cameraId: stream, - role, - oldReconnectTimer, - newReconnectTimer, - }, - }, 'Camera VIEWER failed. Reconnecting.'); - - this.reconnect(stream, isLocal); - } else { - // Peer that timed out is a sharer/publisher, clean it up, stop. - logger.error({ - logCode: 'video_provider_camera_share_timeout', - extraInfo: { - cameraId: stream, - role, - }, - }, 'Camera SHARER failed.'); - VideoService.notify(intl.formatMessage(intlClientErrors.mediaFlowTimeout)); - this.stopWebRTCPeer(stream, false); - } - }; - } - - _onWebRTCError(error, stream, isLocal) { - const { intl, streams } = this.props; - const { name: errorName, message: errorMessage } = error; - const errorLocale = intlClientErrors[errorName] - || intlClientErrors[errorMessage] - || intlSFUErrors[error]; - - logger.error({ - logCode: 'video_provider_webrtc_peer_error', - extraInfo: { - cameraId: stream, - role: VideoService.getRole(isLocal), - errorName: error.name, - errorMessage: error.message, - }, - }, 'Camera peer failed'); - - // Only display WebRTC negotiation error toasts to sharers. The viewer streams - // will try to autoreconnect silently, but the error will log nonetheless - if (isLocal) { - this.stopWebRTCPeer(stream, false); - if (errorLocale) VideoService.notify(intl.formatMessage(errorLocale)); - } else { - // If it's a viewer, set the reconnection timeout. There's a good chance - // no local candidate was generated and it wasn't set. - const peer = this.webRtcPeers[stream]; - const stillExists = streams.some(({ stream: streamId }) => streamId === stream); - - if (stillExists) { - const isEstablishedConnection = peer && peer.started; - this.setReconnectionTimeout(stream, isLocal, isEstablishedConnection); - } - - // second argument means it will only try to reconnect if - // it's a viewer instance (see stopWebRTCPeer restarting argument) - this.stopWebRTCPeer(stream, stillExists); - } - } - - reconnect(stream, isLocal) { - this.stopWebRTCPeer(stream, true); - this.createWebRTCPeer(stream, isLocal); - } - - setReconnectionTimeout(stream, isLocal, isEstablishedConnection) { - const peer = this.webRtcPeers[stream]; - const shouldSetReconnectionTimeout = !this.restartTimeout[stream] && !isEstablishedConnection; - - // This is an ongoing reconnection which succeeded in the first place but - // then failed mid call. Try to reconnect it right away. Clear the restart - // timers since we don't need them in this case. - if (isEstablishedConnection) { - this.clearRestartTimers(stream); - return this.reconnect(stream, isLocal); - } - - // This is a reconnection timer for a peer that hasn't succeeded in the first - // place. Set reconnection timeouts with random intervals between them to try - // and reconnect without flooding the server - if (shouldSetReconnectionTimeout) { - const newReconnectTimer = this.restartTimer[stream] || CAMERA_SHARE_FAILED_WAIT_TIME; - this.restartTimer[stream] = newReconnectTimer; - - this.restartTimeout[stream] = setTimeout( - this._getWebRTCStartTimeout(stream, isLocal), - this.restartTimer[stream] - ); - } - } - - _getOnIceCandidateCallback(stream, isLocal) { - if (SIGNAL_CANDIDATES) { - return (candidate) => { - const peer = this.webRtcPeers[stream]; - const role = VideoService.getRole(isLocal); - - if (peer && !peer.didSDPAnswered) { - this.outboundIceQueues[stream].push(candidate); - return; - } - - this.sendIceCandidateToSFU(peer, role, candidate, stream); - }; - } - - return null; - } - - sendIceCandidateToSFU(peer, role, candidate, stream) { - const message = { - type: 'video', - role, - id: 'onIceCandidate', - candidate, - cameraId: stream, - }; - this.sendMessage(message); - } - - _handleLocalStreamInactive(stream) { - const peer = this.webRtcPeers[stream]; - const isLocal = VideoService.isLocalStream(stream); - const role = VideoService.getRole(isLocal); - - // Peer == null: this is a trailing event. - // !isLocal: someone is misusing this handler - local streams only. - if (peer == null || !isLocal) return; - - logger.error({ - logCode: 'video_provider_local_stream_inactive', - extraInfo: { - cameraId: stream, - role, - }, - }, 'Local camera stream stopped unexpectedly'); - - const error = new Error('inactiveError'); - this._onWebRTCError(error, stream, isLocal); - } - - _handleIceConnectionStateChange(stream, isLocal) { - const { intl } = this.props; - const peer = this.webRtcPeers[stream]; - const role = VideoService.getRole(isLocal); - - if (peer && peer.peerConnection) { - const pc = peer.peerConnection; - const connectionState = pc.connectionState; - notifyStreamStateChange(stream, connectionState); - - if (connectionState === 'failed' || connectionState === 'closed') { - const error = new Error('iceConnectionStateError'); - // prevent the same error from being detected multiple times - pc.onconnectionstatechange = null; - - logger.error({ - logCode: 'video_provider_ice_connection_failed_state', - extraInfo: { - cameraId: stream, - connectionState, - role, - }, - }, `Camera ICE connection state changed: ${connectionState}. Role: ${role}.`); - - this._onWebRTCError(error, stream, isLocal); - } - } else { - logger.error({ - logCode: 'video_provider_ice_connection_nopeer', - extraInfo: { cameraId: stream, role }, - }, `No peer at ICE connection state handler. Camera: ${stream}. Role: ${role}`); - } - } - - attach (peer, videoElement) { - if (peer && videoElement) { - const stream = peer.isPublisher ? peer.getLocalStream() : peer.getRemoteStream(); - videoElement.pause(); - videoElement.srcObject = stream; - videoElement.load(); - } - } - - getVideoElement(streamId) { - return this.videoTags[streamId]; - } - - attachVideoStream(stream) { - const videoElement = this.getVideoElement(stream); - const isLocal = VideoService.isLocalStream(stream); - const peer = this.webRtcPeers[stream]; - - if (VideoProvider.shouldAttachVideoStream(peer, videoElement)) { - const pc = peer.peerConnection; - // Notify current stream state again on attachment since the - // video-list-item component may not have been mounted before the stream - // reached the connected state. - // This is necessary to ensure that the video element is properly - // hidden/shown when the stream is attached. - notifyStreamStateChange(stream, pc.connectionState); - this.attach(peer, videoElement); - - if (isLocal) { - if (peer.bbbVideoStream == null) { - this.handleVirtualBgError(new TypeError('Undefined media stream')); - return; - } - - const deviceId = MediaStreamUtils.extractDeviceIdFromStream( - peer.bbbVideoStream.mediaStream, - 'video', - ); - const { type, name } = getSessionVirtualBackgroundInfo(deviceId); - - this.restoreVirtualBackground(peer.bbbVideoStream, type, name).catch((error) => { - this.handleVirtualBgError(error, type, name); - }); - } - } - } - - startVirtualBackgroundByDrop(stream, type, name, data) { - return new Promise((resolve, reject) => { - const peer = this.webRtcPeers[stream]; - const { bbbVideoStream } = peer; - const video = this.getVideoElement(stream); - - if (peer && video && video.srcObject) { - bbbVideoStream.startVirtualBackground(type, name, { file: data }) - .then(resolve) - .catch(reject); - } - }).catch((error) => { - this.handleVirtualBgErrorByDropping(error, type, name); - }); - } - - handleVirtualBgErrorByDropping(error, type, name) { - logger.error({ - logCode: `video_provider_virtualbg_error`, - extraInfo: { - errorName: error.name, - errorMessage: error.message, - virtualBgType: type, - virtualBgName: name, - }, - }, `Failed to start virtual background by dropping image: ${error.message}`); - } - - restoreVirtualBackground(stream, type, name) { - return new Promise((resolve, reject) => { - if (type !== EFFECT_TYPES.NONE_TYPE) { - stream.startVirtualBackground(type, name).then(() => { - resolve(); - }).catch((error) => { - reject(error); - }); - } - resolve(); - }); - } - - handleVirtualBgError(error, type, name) { - const { intl } = this.props; - logger.error({ - logCode: `video_provider_virtualbg_error`, - extraInfo: { - errorName: error.name, - errorMessage: error.message, - virtualBgType: type, - virtualBgName: name, - }, - }, `Failed to restore virtual background after reentering the room: ${error.message}`); - - notify(intl.formatMessage(intlClientErrors.virtualBgGenericError), 'error', 'video'); - } - - createVideoTag(stream, video) { - const peer = this.webRtcPeers[stream]; - this.videoTags[stream] = video; - - if (peer && peer.stream === stream) { - this.attachVideoStream(stream); - } - } - - destroyVideoTag(stream) { - const videoElement = this.videoTags[stream]; - - if (videoElement == null) return; - - if (typeof videoElement.pause === 'function') { - videoElement.pause(); - videoElement.srcObject = null; - } - - delete this.videoTags[stream]; - } - - handlePlayStop(message) { - const { intl } = this.props; - const { cameraId: stream, role } = message; - - logger.info({ - logCode: 'video_provider_handle_play_stop', - extraInfo: { - cameraId: stream, - role, - }, - }, `Received request from SFU to stop camera. Role: ${role}`); - - VideoService.notify(intl.formatMessage(intlClientErrors.mediaTimedOutError)); - this.stopWebRTCPeer(stream, false); - } - - handlePlayStart(message) { - const { cameraId: stream, role } = message; - const peer = this.webRtcPeers[stream]; - const { playStart } = this.props; - - if (peer) { - logger.info({ - logCode: 'video_provider_handle_play_start_flowing', - extraInfo: { - cameraId: stream, - role, - }, - }, `Camera media is flowing (server). Role: ${role}`); - - peer.started = true; - - // Clear camera shared timeout when camera successfully starts - this.clearRestartTimers(stream); - this.attachVideoStream(stream); - - playStart(stream); - } else { - logger.warn({ - logCode: 'video_provider_playstart_no_peer', - extraInfo: { cameraId: stream, role }, - }, 'Trailing camera playStart response.'); - } - } - - handleSFUError(message) { - const { intl, streams, sendUserUnshareWebcam } = this.props; - const { code, reason, streamId } = message; - const isLocal = VideoService.isLocalStream(streamId); - const role = VideoService.getRole(isLocal); - - logger.error({ - logCode: 'video_provider_handle_sfu_error', - extraInfo: { - errorCode: code, - errorReason: reason, - cameraId: streamId, - role, - }, - }, `SFU returned an error. Code: ${code}, reason: ${reason}`); - - if (isLocal) { - // The publisher instance received an error from the server. There's no reconnect, - // stop it. - VideoService.notify(intl.formatMessage(intlSFUErrors[code] || intlSFUErrors[2200])); - VideoService.stopVideo(streamId, sendUserUnshareWebcam); - } else { - const peer = this.webRtcPeers[streamId]; - const stillExists = streams.some(({ stream }) => streamId === stream); - - if (stillExists) { - const isEstablishedConnection = peer && peer.started; - this.setReconnectionTimeout(streamId, isLocal, isEstablishedConnection); - } - - this.stopWebRTCPeer(streamId, stillExists); - } - } - - replacePCVideoTracks(streamId, mediaStream) { - const peer = this.webRtcPeers[streamId]; - const videoElement = this.getVideoElement(streamId); - - if (peer == null || mediaStream == null || videoElement == null) return; - - const pc = peer.peerConnection; - const newTracks = mediaStream.getVideoTracks(); - - if (pc) { - const trackReplacers = pc.getSenders().map(async (sender, index) => { - if (sender.track == null || sender.track.kind !== 'video') return false; - const newTrack = newTracks[index]; - if (newTrack == null) return false; - try { - await sender.replaceTrack(newTrack); - return true; - } catch (error) { - logger.warn({ - logCode: 'video_provider_replacepc_error', - extraInfo: { errorMessage: error.message, cameraId: streamId }, - }, `Failed to replace peer connection tracks: ${error.message}`); - return false; - } - }); - Promise.all(trackReplacers).then(() => { - this.attach(peer, videoElement); - }); - } - } - - render() { - const { - swapLayout, - currentVideoPageIndex, - streams, - cameraDockBounds, - focusedId, - handleVideoFocus, - isGridEnabled, - users, - } = this.props; - - return ( - - ); - } -} - -VideoProvider.propTypes = propTypes; - -export default injectIntl(VideoProvider); diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/video-provider-graphql/component.tsx b/bigbluebutton-html5/imports/ui/components/video-provider/component.tsx similarity index 90% rename from bigbluebutton-html5/imports/ui/components/video-provider/video-provider-graphql/component.tsx rename to bigbluebutton-html5/imports/ui/components/video-provider/component.tsx index ae655e8ed0..f3f83a3c7f 100755 --- a/bigbluebutton-html5/imports/ui/components/video-provider/video-provider-graphql/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/video-provider/component.tsx @@ -22,34 +22,9 @@ import { import { notify } from '/imports/ui/services/notification'; import { shouldForceRelay } from '/imports/ui/services/bbb-webrtc-sfu/utils'; import WebRtcPeer from '/imports/ui/services/webrtc-base/peer'; -import { StreamItem, StreamUser, VideoItem } from './types'; -import { Output } from '../../layout/layoutTypes'; - -// Default values and default empty object to be backwards compat with 2.2. -// FIXME Remove hardcoded defaults 2.3. -const { - connectionTimeout: WS_CONN_TIMEOUT = 4000, - maxRetries: WS_MAX_RETRIES = 5, - debug: WS_DEBUG, - heartbeat: WS_HEARTBEAT_OPTS = { - interval: 15000, - delay: 3000, - reconnectOnFailure: true, - }, -} = window.meetingClientSettings.public.kurento.cameraWsOptions; - -const { webcam: NETWORK_PRIORITY } = window.meetingClientSettings.public.media.networkPriorities || {}; -const { - baseTimeout: CAMERA_SHARE_FAILED_WAIT_TIME = 15000, - maxTimeout: MAX_CAMERA_SHARE_FAILED_WAIT_TIME = 60000, -} = window.meetingClientSettings.public.kurento.cameraTimeouts || {}; -const { - enabled: CAMERA_QUALITY_THRESHOLDS_ENABLED = true, - privilegedStreams: CAMERA_QUALITY_THR_PRIVILEGED = true, -} = window.meetingClientSettings.public.kurento.cameraQualityThresholds; -const SIGNAL_CANDIDATES = window.meetingClientSettings.public.kurento.signalCandidates; -const TRACE_LOGS = window.meetingClientSettings.public.kurento.traceLogs; -const GATHERING_TIMEOUT = window.meetingClientSettings.public.kurento.gatheringTimeout; +import { StreamItem, VideoItem } from './types'; +import { Output } from '/imports/ui/components/layout/layoutTypes'; +import { VIDEO_TYPES } from './enums'; const intlClientErrors = defineMessages({ permissionError: { @@ -117,16 +92,16 @@ const intlSFUErrors = defineMessages({ }, }); -interface VideoProviderGraphqlState { +interface VideoProviderState { socketOpen: boolean; } -interface VideoProviderGraphqlProps { +interface VideoProviderProps { cameraDock: Output['cameraDock']; focusedId: string; handleVideoFocus: (id: string) => void; isGridEnabled: boolean; - isMeteorConnected: boolean; + isClientConnected: boolean; swapLayout: boolean; currentUserId: string; paginationEnabled: boolean; @@ -135,7 +110,6 @@ interface VideoProviderGraphqlProps { isUserLocked: boolean; currentVideoPageIndex: number; streams: VideoItem[]; - users: StreamUser[]; info: { userId: string | null | undefined; userName: string | null | undefined; @@ -147,10 +121,12 @@ interface VideoProviderGraphqlProps { exitVideo: () => void; lockUser: () => void; stopVideo: (cameraId?: string) => void; + applyCameraProfile: (peer: WebRtcPeer, profileId: string) => void; intl: IntlShape; + myRole: string | undefined; } -class VideoProviderGraphql extends Component { +class VideoProvider extends Component { onBeforeUnload() { const { exitVideo } = this.props; exitVideo(); @@ -209,7 +185,7 @@ class VideoProviderGraphql extends Component; - constructor(props: VideoProviderGraphqlProps) { + constructor(props: VideoProviderProps) { super(props); const { info } = this.props; @@ -250,12 +226,12 @@ class VideoProviderGraphql extends Component stream.type === 'stream' && (stream.floor || stream.pin)); + return streams.filter((stream) => stream.type === VIDEO_TYPES.STREAM && (stream.floor || stream.pinned)); } updateQualityThresholds(numberOfPublishers: number) { + const { + privilegedStreams: CAMERA_QUALITY_THR_PRIVILEGED = true, + } = window.meetingClientSettings.public.kurento.cameraQualityThresholds; + + const { applyCameraProfile } = this.props; + const { threshold, profile } = VideoService.getThreshold(numberOfPublishers); if (profile) { const privilegedStreams = this.findAllPrivilegedStreams(); @@ -464,13 +464,13 @@ class VideoProviderGraphql extends Component vs.stream === peer.stream)) const profileToApply = exempt ? peer.originalProfileId : profile; - VideoService.applyCameraProfile(peer, profileToApply); + applyCameraProfile(peer, profileToApply); }); } } getStreamsToConnectAndDisconnect(streams: VideoItem[]) { - const streamsCameraIds = streams.filter((s) => s?.type !== 'grid').map((s) => (s as StreamItem).stream); + const streamsCameraIds = streams.filter((s) => s?.type !== VIDEO_TYPES.GRID).map((s) => (s as StreamItem).stream); const streamsConnected = Object.keys(this.webRtcPeers); const streamsToConnect = streamsCameraIds.filter((stream) => { @@ -506,6 +506,10 @@ class VideoProviderGraphql extends Component { const role = VideoService.getRole(isLocal); if (!isLocal) { @@ -951,7 +964,7 @@ class VideoProviderGraphql extends Component item.type === 'stream' && item.stream === stream); + const stillExists = streams.some((item) => item.type === VIDEO_TYPES.STREAM && item.stream === stream); if (stillExists) { const isEstablishedConnection = peer && peer.started; @@ -973,6 +986,10 @@ class VideoProviderGraphql extends Component { const peer = this.webRtcPeers[stream]; @@ -1097,7 +1116,7 @@ class VideoProviderGraphql extends Component