diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 973be812..00000000 --- a/.babelrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "presets": [ - "@babel/preset-react", - "@babel/preset-env", - "@babel/preset-typescript" - ], - "plugins": [ - "@babel/proposal-class-properties", - "@babel/proposal-object-rest-spread", - "@babel/plugin-syntax-object-rest-spread" - ] - -} diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 9b269ed6..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,137 +0,0 @@ -version: 2 -jobs: - build: - docker: - - image: circleci/node:12.13.1 - steps: - - checkout - - restore_cache: - keys: - - v1-node-cache-{{ .Branch }}-{{ checksum "yarn.lock" }} - - v1-node-cache-{{ .Branch }} - - run: - name: yarn install - command: yarn install --check-files #--frozen-lockfile - no_output_timeout: 60m - - run: yarn validate:dependencies - - run: - name: yarn build - command: yarn build - no_output_timeout: 60m - - run: - name: yarn unit test - command: yarn unit - no_output_timeout: 60m - # TODO: check dev depencies: - #- run: - # name: yarn install production - # command: yarn install --check-files --frozen-lockfile --production --force - # no_output_timeout: 60m - - save_cache: - key: v1-node-cache-{{ .Branch }}-{{ checksum "yarn.lock" }} - paths: - - node_modules - - save_cache: - key: v3-node-cache-{{ .Branch }} - paths: - - node_modules - - persist_to_workspace: - root: . - paths: - - . - publish-tag: - docker: - - image: circleci/buildpack-deps:stretch - steps: - - setup_remote_docker: - # docker_layer_caching: true - version: 18.06.0-ce - - attach_workspace: - at: . - - run: - name: Build Docker Image - command: docker build -f Dockerfile . -t olzzon/sisyfos-audio-controller:$CIRCLE_TAG - - run: - name: Publish Docker Image to Docker Hub - command: | - if [ -z "$DOCKERHUB_PASS" ]; then - echo "Skipping" - else - echo "$DOCKERHUB_PASS" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin - docker tag olzzon/sisyfos-audio-controller:$CIRCLE_TAG $DOCKERHUB_IMAGE:$CIRCLE_TAG - docker push $DOCKERHUB_IMAGE:$CIRCLE_TAG - fi - - run: - name: Publish Docker Image to Github Package Registry - command: | - if [ -z "$GITHUB_PASS" ]; then - echo "Skipping" - else - echo "$GITHUB_PASS" | docker login docker.pkg.github.com -u "$GITHUB_USERNAME" --password-stdin - docker tag olzzon/sisyfos-audio-controller:$CIRCLE_TAG docker.pkg.github.com/$GITHUB_IMAGE:$CIRCLE_TAG - docker push docker.pkg.github.com/$GITHUB_IMAGE:$CIRCLE_TAG - fi - publish-branch: - docker: - - image: circleci/buildpack-deps:stretch - steps: - - setup_remote_docker: - # docker_layer_caching: true - version: 18.06.0-ce - - attach_workspace: - at: . - - run: - name: Build Docker Image - command: docker build -f Dockerfile . -t olzzon/sisyfos-audio-controller:$CIRCLE_BRANCH - - run: - name: Publish Docker Image to Docker Hub - command: | - if [ -z "$DOCKERHUB_PASS" ]; then - echo "Skipping" - else - echo "$DOCKERHUB_PASS" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin - docker tag olzzon/sisyfos-audio-controller:$CIRCLE_BRANCH $DOCKERHUB_IMAGE:$CIRCLE_BRANCH - docker push $DOCKERHUB_IMAGE:$CIRCLE_BRANCH - fi - - run: - name: Publish Docker Image to Github Package Registry - command: | - if [ -z "$GITHUB_PASS" ]; then - echo "Skipping" - else - echo "$GITHUB_PASS" | docker login docker.pkg.github.com -u "$GITHUB_USERNAME" --password-stdin - docker tag olzzon/sisyfos-audio-controller:$CIRCLE_BRANCH docker.pkg.github.com/$GITHUB_IMAGE:$CIRCLE_BRANCH - docker push docker.pkg.github.com/$GITHUB_IMAGE:$CIRCLE_BRANCH - fi - - -workflows: - version: 2 - build-test-publish: - jobs: - - build: - filters: - tags: - only: /v.*/ - branches: - only: /.*/ - - publish-tag: - requires: - - build - filters: - tags: - only: /v.*/ - branches: - ignore: /.*/ - - publish-branch: - requires: - - build - filters: - tags: - ignore: /v.*/ - branches: - only: - - master - - develop - - stage - - /release\d+/ diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..1d9bad66 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,20 @@ +node_modules +*.vscode +*.github +Dockerfile +Docs + +*/dist +desktop + +.gitignore +.dockerignore +.prettierignore +.prettierrc.json +jest.config.js +tsconfig.jest.json +tslint.json +.npmignore +.jshintrc +.editorconfig +webpack.config.js diff --git a/.github/actions/branch-exists/action.yml b/.github/actions/branch-exists/action.yml new file mode 100644 index 00000000..96d87668 --- /dev/null +++ b/.github/actions/branch-exists/action.yml @@ -0,0 +1,28 @@ +####################################################################################################################### +# NOTE: DOES NOT WORK YET +####################################################################################################################### + +name: 'Branch exists' +description: 'Check that branch exists' +inputs: + branch: + description: 'branch to check existence for' + required: true +outputs: + exists: + description: "Boolean of whether branch exists" + value: ${{ steps.branch.outputs.exists }} +runs: + using: 'composite' + steps: + - name: Check branch + id: branch + env: + branch: ${{ inputs.branch }} + shell: bash + run: | + if [ -z $(git show-ref -- heads/$branch) ]; then + echo ::set-output name=exists::false + else + echo ::set-output name=exists::true + fi diff --git a/.github/actions/cache/action.yml b/.github/actions/cache/action.yml new file mode 100644 index 00000000..55e7abd3 --- /dev/null +++ b/.github/actions/cache/action.yml @@ -0,0 +1,10 @@ +name: "Cache dependencies" +description: "Cache dependencies" +runs: + using: "composite" + steps: + - name: Cache dependencies + uses: actions/setup-node@v2 + with: + node-version: ${{ env.node-version }} + cache: ${{ env.node-package-manager }} \ No newline at end of file diff --git a/.github/actions/check-secret/action.yml b/.github/actions/check-secret/action.yml new file mode 100644 index 00000000..11883a6b --- /dev/null +++ b/.github/actions/check-secret/action.yml @@ -0,0 +1,24 @@ +name: 'Check secret' +description: 'Check secret' +inputs: + secret: + description: 'Secret to check' + required: true +outputs: + defined: + description: "Boolean of whether secret is defined" + value: ${{ steps.secret.outputs.defined }} +runs: + using: 'composite' + steps: + - name: Check secrets + id: secret + env: + secret: ${{ inputs.secret }} + shell: bash + run: | + if [ "$secret" == "" ]; then + echo ::set-output name=defined::false + else + echo ::set-output name=defined::true + fi diff --git a/.github/actions/extract-version/action.yml b/.github/actions/extract-version/action.yml new file mode 100644 index 00000000..2328644e --- /dev/null +++ b/.github/actions/extract-version/action.yml @@ -0,0 +1,30 @@ +name: 'Extract version' +description: 'Split semver version into major, minor and patch (and version).' +inputs: + version: + description: 'Version as string' + required: true +outputs: + version: + description: "Full version" + value: ${{ steps.match.outputs.group1 }} + major: + description: "Major version" + value: ${{ steps.match.outputs.group2 }} + minor: + description: "Minor version" + value: ${{ steps.match.outputs.group3 }} + patch: + description: "Patch version" + value: ${{ steps.match.outputs.group4 }} +runs: + using: 'composite' + steps: + - run: echo "${{ inputs.version }}" + shell: bash + - name: Match Semantic Version + uses: actions-ecosystem/action-regex-match@v2 + id: match + with: + text: ${{ inputs.version }} + regex: '^v?(?(?[0-9]+).(?[0-9]+).(?[0-9]+))$' diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml new file mode 100644 index 00000000..b03b3391 --- /dev/null +++ b/.github/actions/test/action.yml @@ -0,0 +1,12 @@ +name: "Test" +description: "Test" +runs: + using: "composite" + steps: + - uses: ./.github/actions/cache + - name: Install dependencies + run: yarn install --frozen-lockfile + shell: bash + - name: Run tests + run: yarn test + shell: bash \ No newline at end of file diff --git a/.github/actions/validate-dependencies/action.yml b/.github/actions/validate-dependencies/action.yml new file mode 100644 index 00000000..59b0ad95 --- /dev/null +++ b/.github/actions/validate-dependencies/action.yml @@ -0,0 +1,8 @@ +name: "Validate dependencies" +description: "Validate dependencies" +runs: + using: "composite" + steps: + - name: Check dependencies + run: yarn audit --groups "dependencies" --level moderate + shell: bash \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..e8079d99 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + reviewers: + - "@nrkno/sofie-ops" diff --git a/.github/version b/.github/version new file mode 100644 index 00000000..ffa1d973 --- /dev/null +++ b/.github/version @@ -0,0 +1 @@ +1.11.6-locally-modified diff --git a/.github/workflows/deploy-image.yml b/.github/workflows/deploy-image.yml new file mode 100644 index 00000000..4351c547 --- /dev/null +++ b/.github/workflows/deploy-image.yml @@ -0,0 +1,78 @@ +name: Node CI +on: + push: + branches: + - '**' + tags: + - 'v**' + workflow_dispatch: + +jobs: + run-yarn-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - uses: actions/cache@v3 + with: + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: yarn install + run: yarn install --check-files --frozen-lockfile + + # - name: yarn validate:dependencies + # run: | + # if ! git log --format=oneline -n 1 | grep -q "\[ignore-audit\]"; then + # yarn validate:dependencies + # else + # echo "Skipping audit" + # fi + + - name: yarn build + run: yarn build + + - name: yarn unit test + run: yarn test + + docker-release: + runs-on: ubuntu-latest + needs: [run-yarn-build] + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v3 + + - name: Get the Docker tag for GHCR + id: ghcr-tag + uses: docker/metadata-action@v4 + with: + images: | + ghcr.io/${{ github.repository }} + tags: | + type=schedule + type=ref,event=branch + type=ref,event=tag + type=raw,value=latest,enable={{is_default_branch}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push to GHCR + uses: docker/build-push-action@v3 + with: + context: . + push: true + provenance: false + labels: ${{ steps.ghcr-tag.outputs.labels }} + tags: "${{ steps.ghcr-tag.outputs.tags }}" diff --git a/.github/workflows/node-ci.dev.yml b/.github/workflows/node-ci.dev.yml new file mode 100644 index 00000000..7a34f1ed --- /dev/null +++ b/.github/workflows/node-ci.dev.yml @@ -0,0 +1,126 @@ +name: Dev Node CI + +env: + node-version: 16 + node-package-manager: yarn + +# on: +# push: +# branches: +# - "develop" + +jobs: + cache-dependencies: + runs-on: ubuntu-latest + steps: + - name: Access repository + uses: actions/checkout@v2 + - uses: ./.github/actions/cache + - name: Install dependencies + run: yarn install --frozen-lockfile + + test: + runs-on: ubuntu-latest + needs: cache-dependencies + steps: + - name: Access repository + uses: actions/checkout@v2 + - uses: ./.github/actions/test + + # validate-dependencies: + # runs-on: ubuntu-latest + # steps: + # - name: Access repository + # uses: actions/checkout@v2 + # - uses: ./.github/actions/validate-dependencies + + build: + runs-on: ubuntu-latest + needs: + - test + - validate-dependencies + steps: + - name: Access repository + uses: actions/checkout@v2 + - uses: ./.github/actions/cache + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Build + run: yarn build + + - name: Upload client build artifact + uses: actions/upload-artifact@v2 + with: + name: ${{ github.event.repository.name }}-client-develop + path: client/dist + + - name: Upload server build artifact + uses: actions/upload-artifact@v2 + with: + name: ${{ github.event.repository.name }}-server-develop + path: server/dist + + check-docker-credentials: + runs-on: ubuntu-latest + needs: build + outputs: + defined: ${{ steps.username.outputs.defined == 'true' && steps.password.outputs.defined == 'true' }} + steps: + - name: Access repository + uses: actions/checkout@v2 + + - name: Check if has username + id: username + uses: ./.github/actions/check-secret + with: + secret: ${{ secrets.DOCKER_USERNAME }} + + - name: Check if has password + id: password + uses: ./.github/actions/check-secret + with: + secret: ${{ secrets.DOCKER_PASSWORD }} + + publish-docker-image: + runs-on: ubuntu-latest + if: needs.check-docker-credentials.outputs.defined == 'true' + needs: + - check-docker-credentials + steps: + - name: Access repository + uses: actions/checkout@v2 + + - uses: actions/download-artifact@v2 + with: + name: ${{ github.event.repository.name }}-client-develop + path: client/dist + + - uses: actions/download-artifact@v2 + with: + name: ${{ github.event.repository.name }}-server-develop + path: server/dist + + - name: Docker meta + id: meta + uses: docker/metadata-action@v3 + with: + images: 'tv2media/${{ github.event.repository.name }}' + tags: | + type=ref,event=branch + + - name: Log in to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + diff --git a/.github/workflows/node-ci.prod.yml b/.github/workflows/node-ci.prod.yml new file mode 100644 index 00000000..31642791 --- /dev/null +++ b/.github/workflows/node-ci.prod.yml @@ -0,0 +1,335 @@ +####################################################################################################################### +# +# Node CI - Production +# +# The workflow ensures quality for the build, builds the project and publishes it to the configured destinations. +# There are the following destinations: +# +# [Github Release] +# The destination is only triggered if the secret 'RELEASE_TO_GITHUB' is set to a non-empty value. +# +# [NPM] +# The destination is only triggered if the secret 'NPM_TOKEN' is provided. +# +# [Docker Hub] +# The destination is only triggered if the secrets 'DOCKER_USERNAME' and 'DOCKER_PASSWORD' are +# provided. +# +####################################################################################################################### + +name: Prod Node CI + +env: + node-version: 16 + node-package-manager: yarn + +# on: +# push: +# branches: +# - "master" +# - "main" + +jobs: + cache-dependencies: + runs-on: ubuntu-latest + steps: + - name: Access repository + uses: actions/checkout@v2 + - uses: ./.github/actions/cache + - name: Install dependencies + run: yarn install --frozen-lockfile + + prebuild: + runs-on: ubuntu-latest + needs: cache-dependencies + steps: + - name: Access repository + uses: actions/checkout@v2 + - uses: ./.github/actions/cache + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Build + run: yarn build + + test: + runs-on: ubuntu-latest + needs: cache-dependencies + steps: + - name: Access repository + uses: actions/checkout@v2 + + - uses: ./.github/actions/test + + # validate-dependencies: + # runs-on: ubuntu-latest + # steps: + # - name: Access repository + # uses: actions/checkout@v2 + # - uses: ./.github/actions/validate-dependencies + + bump-version: + runs-on: ubuntu-latest + needs: + - prebuild + - test + - validate-dependencies + outputs: + tag_version: ${{ steps.tag_version.outputs.new_tag || steps.tag_version.outputs.previous_tag }} + version: ${{ steps.tag_version.outputs.new_version || steps.tag_version.outputs.previous_version }} + changelog: ${{ steps.tag_version.outputs.changelog }} + bumped: ${{ steps.tag_version.outputs.new_tag != '' }} + commit_sha: ${{ steps.commit_sha.outputs.commit_sha }} + steps: + - name: Access repository + uses: actions/checkout@v2 + - name: Configure committer + run: | + git config user.name "${{ github.event.pusher.name }}" + git config user.email "${{ github.event.pusher.email }}" + - name: Bump version and push tag + id: tag_version + uses: mathieudutour/github-tag-action@v5.6 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + default_bump: false + - name: Update package.json + if: steps.tag_version.outputs.new_tag != '' + uses: jossef/action-set-json-field@v1 + with: + file: package.json + field: version + value: ${{ steps.tag_version.outputs.new_version }} + - name: Update CHANGELOG.md + env: + changes: ${{ steps.tag_version.outputs.changelog }} + run: | + echo "$changes" > /tmp/tmp-changelog.md + [ -f CHANGELOG.md ] && cat CHANGELOG.md >> /tmp/tmp-changelog.md + mv /tmp/tmp-changelog.md CHANGELOG.md + + - name: Commit and push changes to package.json and CHANGELOG.md + id: commit_sha + if: steps.tag_version.outputs.new_tag != '' + uses: EndBug/add-and-commit@v7 + with: + add: "['package.json', 'CHANGELOG.md']" + + create-pull-request-develop: + runs-on: ubuntu-latest + if: needs.bump-version.outputs.bumped == 'true' + needs: + - bump-version + steps: + - name: Access repository + uses: actions/checkout@v2 + - name: Pull request to develop + id: develop + continue-on-error: true + uses: repo-sync/pull-request@v2 + with: + destination_branch: 'develop' + github_token: ${{ secrets.GITHUB_TOKEN }} + pr_label: 'release, automated-pr' + pr_title: 'Release ${{ needs.bump-version.outputs.version }} -> develop' + - name: Report status + env: + report: ${{ toJSON(steps.develop.outcome) }} - ${{ toJSON(steps.develop.conclusion) }} + run: echo $report + + build: + runs-on: ubuntu-latest + needs: + - bump-version + steps: + - name: Access repository + uses: actions/checkout@v2 + with: + ref: ${{ needs.bump-version.outputs.commit_sha }} + - name: Ensure commits from bump-version + run: git pull + - uses: ./.github/actions/cache + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Build + run: yarn build + - name: Upload client build artifact + uses: actions/upload-artifact@v2 + with: + name: ${{ github.event.repository.name }}-client + path: client/dist + - name: Upload server build artifact + uses: actions/upload-artifact@v2 + with: + name: ${{ github.event.repository.name }}-server + path: server/dist + + build-desktop: + runs-on: windows-latest + needs: + - bump-version + - build + steps: + - name: Access repository + uses: actions/checkout@v2 + with: + ref: ${{ needs.bump-version.outputs.commit_sha }} + - name: Ensure commits from bump-version + run: git pull + - uses: ./.github/actions/cache + - uses: actions/download-artifact@v2 + with: + name: ${{ github.event.repository.name }}-client + path: client/dist + - uses: actions/download-artifact@v2 + with: + name: ${{ github.event.repository.name }}-server + path: server/dist + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Build desktop + run: yarn build:desktop + - name: Upload desktop build artifact + uses: actions/upload-artifact@v2 + with: + name: ${{ github.event.repository.name }}-desktop + path: desktop/dist + + check-github-release: + runs-on: ubuntu-latest + needs: build-desktop + outputs: + defined: ${{ steps.release.outputs.defined == 'true' }} + steps: + - name: Access repository + uses: actions/checkout@v2 + - name: Check if is set to release + id: release + uses: ./.github/actions/check-secret + with: + secret: ${{ secrets.RELEASE_TO_GITHUB }} + + publish-github-release: + runs-on: ubuntu-latest + if: needs.bump-version.outputs.bumped == 'true' && needs.check-github-release.outputs.defined == 'true' + needs: + - bump-version + - check-github-release + steps: + - name: Access repository + uses: actions/checkout@v2 + with: + ref: ${{ needs.bump-version.outputs.commit_sha }} + - name: Ensure commits from bump-version + run: git pull + - uses: actions/download-artifact@v2 + with: + name: ${{ github.event.repository.name }}-desktop + path: desktop/dist + - name: Compress artifact to zip + uses: papeloto/action-zip@v1 + with: + files: dist + dest: '${{ github.event.repository.name }}-${{ needs.bump-version.outputs.version }}.zip' + - name: Create Github release with desktop exe + uses: softprops/action-gh-release@v1 + with: + name: Release ${{ needs.bump-version.outputs.tag_version }} + tag_name: ${{ needs.bump-version.outputs.tag_version }} + body: ${{ needs.bump-version.outputs.changelog }} + files: | + desktop/dist/*.exe + desktop/dist/*.dmg + + check-npm-token: + runs-on: ubuntu-latest + needs: build + outputs: + defined: ${{ steps.token.outputs.defined == 'true' }} + steps: + - name: Access repository + uses: actions/checkout@v2 + - name: Check if has username + id: token + uses: ./.github/actions/check-secret + with: + secret: ${{ secrets.NPM_TOKEN }} + + publish-npm-package: + runs-on: ubuntu-latest + if: needs.check-npm-token.outputs.defined == 'true' + needs: + - bump-version + - check-npm-token + steps: + - name: Access repository + uses: actions/checkout@v2 + - name: Configure publisher + run: | + git config user.name "${{ github.event.pusher.name }}" + git config user.email "${{ github.event.pusher.email }}" + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: ${{ github.event.repository.name }} + path: dist + - uses: actions/setup-node@v2 + with: + node-version: '16.x' + registry-url: 'https://registry.npmjs.org' + - name: Publish package + run: yarn publish --access=public --tag latest --new-version "${{ needs.bump-version.outputs.version }}" + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + check-docker-credentials: + runs-on: ubuntu-latest + needs: build + outputs: + defined: ${{ steps.username.outputs.defined == 'true' && steps.password.outputs.defined == 'true' }} + steps: + - name: Access repository + uses: actions/checkout@v2 + - name: Check if has username + id: username + uses: ./.github/actions/check-secret + with: + secret: ${{ secrets.DOCKER_USERNAME }} + - name: Check if has password + id: password + uses: ./.github/actions/check-secret + with: + secret: ${{ secrets.DOCKER_PASSWORD }} + + publish-docker-image: + runs-on: ubuntu-latest + if: needs.check-docker-credentials.outputs.defined == 'true' + needs: + - bump-version + - check-docker-credentials + steps: + - name: Access repository + uses: actions/checkout@v2 + + - name: Extract version for tags + id: version + uses: ./.github/actions/extract-version + with: + version: ${{ needs.bump-version.outputs.version }} + + - name: Log in to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + push: true + tags: | + "tv2media/${{ github.event.repository.name }}:latest" + "tv2media/${{ github.event.repository.name }}:${{ steps.version.outputs.version }}" + "tv2media/${{ github.event.repository.name }}:${{ steps.version.outputs.major }}" + "tv2media/${{ github.event.repository.name }}:${{ steps.version.outputs.major }}.${{ steps.version.outputs.minor }}" + diff --git a/.github/workflows/prune-container-images.yml b/.github/workflows/prune-container-images.yml new file mode 100644 index 00000000..924ac16e --- /dev/null +++ b/.github/workflows/prune-container-images.yml @@ -0,0 +1,19 @@ +name: "Prune container images" + +on: + workflow_dispatch: + schedule: + - cron: '13 9 * * *' + +jobs: + prune-container-images: + uses: nrkno/sofie-github-workflows/.github/workflows/prune-container-images.yml@main + with: + dry-run: false + prune-untagged: true + package-name: sofie-sisyfos-audio-controller + tags-to-keep-regex: | + ^v(\d+) + ^r(\d+) + secrets: + prune-token: ${{ secrets.GHCR_PRUNE_TOKEN }} diff --git a/.gitignore b/.gitignore index 00b78bb8..4f82ac8e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,59 +1,63 @@ -# Build folder and files # -########################## -builds/ - -# Development folders and files # -################################# -.tmp/ -dist/ -coverage/ -node_modules/ -public/ -*.compiled.* -settings.json -*.shot -*.ccg - -# Folder config file # -###################### -Desktop.ini - -# Folder notes # -################ -_ignore/ - -# Log files & folders # -####################### -logs/ -*.log -npm-debug.log* -.npm - -# Packages # -############ -# it's better to unpack these files and commit the raw source -# git has its own built in compression methods -*.7z -*.dmg -*.gz -*.iso -*.jar -*.rar -*.tar -*.zip - -# Photoshop & Illustrator files # -################################# -*.ai -*.eps -*.psd - -# Windows & Mac file caches # -############################# -.DS_Store -Thumbs.db -ehthumbs.db - -# Windows shortcuts # -##################### -*.lnk +# Build folder and files # +########################## +builds/ + +# Development folders and files # +################################# +.tmp/ +dist/ +coverage/ +node_modules/ +release/ +*.compiled.* +settings.json +pages.json +*.shot +*.ccg + +# Folder config file # +###################### +Desktop.ini + +# Folder notes # +################ +_ignore/ + +# Log files & folders # +####################### +logs/ +*.log +npm-debug.log* +.npm + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Photoshop & Illustrator files # +################################# +*.ai +*.eps +*.psd + +# Windows & Mac file caches # +############################# +.DS_Store +Thumbs.db +ehthumbs.db + +# Windows shortcuts # +##################### +*.lnk + +# Exclude JetBrains specific files +.idea diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..2c6cbe4f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "semi": false, + "singleQuote": true +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e0529a8..0ac90202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,380 +1,1091 @@ -# Changelog - -All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. - -### [2.9.5](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.4...v2.9.5) (2020-02-16) - - -### Bug Fixes - -* add preventDefault in onthouchEnd on vo, mute and auto buttons too ([245352a](https://github.com/olzzon/sisyfos-audio-controller/commit/245352a11e1c1b35a7b8d37711ce66c9e82ae838)) - -### [2.9.4](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.3...v2.9.4) (2020-02-15) - - -### Bug Fixes - -* always clear fade timer before setting a new one ([028d666](https://github.com/olzzon/sisyfos-audio-controller/commit/028d66620b81c090d2b12f1c0ffb19bdb0e45f67)) -* avoid crash of Sisyfos when selecting Lawo and Studer premilary protocols ([d130205](https://github.com/olzzon/sisyfos-audio-controller/commit/d13020572f0f83d0b3d7869d6121eaaed9a82b87)) - -### [2.9.3](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.2...v2.9.3) (2020-02-14) - - -### Bug Fixes - -* handling of touch on pgm-vo-mute-auto buttons without the need for /?multitouch=1 ([d58fd1b](https://github.com/olzzon/sisyfos-audio-controller/commit/d58fd1b5bebb51659dd1b29057540ca4b2cdb3e9)) - -### [2.9.2](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.1...v2.9.2) (2020-02-14) - - -### Bug Fixes - -* prevent floating point loop on fader level by setting step to 0.01 ([263d016](https://github.com/olzzon/sisyfos-audio-controller/commit/263d0162e4163cd4b866afe88d50601df23ef8c1)) - -### [2.9.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.0...v2.9.1) (2020-02-14) - - -### Bug Fixes - -* color of fader-handle dependent on pgm-vo-mute state ([5796eec](https://github.com/olzzon/sisyfos-audio-controller/commit/5796eeca8209a2f171e8a1cfa4ff9a33d3bdd0b2)) -* don´t toggle both on touch & click if multitouch is off ([1b46a47](https://github.com/olzzon/sisyfos-audio-controller/commit/1b46a47218eaa7f879ebe9c2c0e65bacc7effbbe)) -* Fader level was reversed (1-0 instead of 0-1) ([4932128](https://github.com/olzzon/sisyfos-audio-controller/commit/4932128a2ed394a3105eba71e9d12a2f5d79c088)) -* update fader handle color on state shift ([e149456](https://github.com/olzzon/sisyfos-audio-controller/commit/e14945687690a1b309a1f557d0221e6ce370b597)) - -## [2.9.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.8.0...v2.9.0) (2020-02-12) - - -### Features - -* multitouch - add css file. set animate to false for better multiclient multitouch support ([5ed9596](https://github.com/olzzon/sisyfos-audio-controller/commit/5ed95962a4434986c47f1b5b3c32291ed11904cc)) -* multitouch - added styling, moved ChanStrip params back to single touch (using react-slider) ([313089e](https://github.com/olzzon/sisyfos-audio-controller/commit/313089e4a02fe6c80962b3c8892368d34ec7ebcf)) -* multitouch - move to NoUISlider to support multitouch. ToDo CSS ([b59d230](https://github.com/olzzon/sisyfos-audio-controller/commit/b59d230d887ae100b8bd3d3d0882571171dbdefe)) -* multitouch - supporteded on pgm, vo, mute and auto buttons. ([7921d9b](https://github.com/olzzon/sisyfos-audio-controller/commit/7921d9b227177c36b0e143d759d714b8076731a5)) - -## [2.8.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.7.1...v2.8.0) (2020-02-11) - - -### Features - -* implement Sofie iFrame support ([a96215a](https://github.com/olzzon/sisyfos-audio-controller/commit/a96215a9675de754296f07d3b0bb06378e2fc6e3)) -* Sisyfos inside iFrame. Use window.top !== window.self to chech if it´s running inside something ([76ceca9](https://github.com/olzzon/sisyfos-audio-controller/commit/76ceca9a193ae2025b649bef83a669879eac952e)) -* Sisyfos running in iFrame. Use frameElement instead of checking parent. ([bcc3633](https://github.com/olzzon/sisyfos-audio-controller/commit/bcc3633e016b6b9ea7afaaf702500b92ae4b0ea6)) - -### [2.7.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.7.0...v2.7.1) (2020-02-07) - -## [2.7.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.6.0...v2.7.0) (2020-02-05) - - -### Features - -* Channelstrip Delay Time generic implementation ([0a5a88c](https://github.com/olzzon/sisyfos-audio-controller/commit/0a5a88ccc3dd3ebbb413d364b084153d7b4cdaf8)) -* chanStrip delaybuttons to fineadjust delay value ([7ee1418](https://github.com/olzzon/sisyfos-audio-controller/commit/7ee1418aa5782999daee8f8dcf95880d436a7de7)) -* chanStrip slide in-out fdrom left ([983cefb](https://github.com/olzzon/sisyfos-audio-controller/commit/983cefb1fd2f3a0906c2d7ab737864ec9900e057)) -* disable label transfer to Midas so Sofie can set userlabels in Sisyfos without interfering with the mixer labels ([0e139eb](https://github.com/olzzon/sisyfos-audio-controller/commit/0e139ebba17c651f5ef7bccd6b7d8e7b84dfc347)) -* Midas receive delayTime state ([de94606](https://github.com/olzzon/sisyfos-audio-controller/commit/de94606eb90d26b74da8160b5a9a3bb2fc5a3a1d)) -* Midas/X32 MUTE button support ([e922d5f](https://github.com/olzzon/sisyfos-audio-controller/commit/e922d5f36c385f81536091649a28ed5f4fab5633)) -* offtube mode, make channelstrip area persistent. ([aebb505](https://github.com/olzzon/sisyfos-audio-controller/commit/aebb505457d7ad58bf510157fd8230b4b341077f)) -* wider chanstrip for support of more aux sends ([f6872db](https://github.com/olzzon/sisyfos-audio-controller/commit/f6872dbcd5eeb5196a41f311fdb7b54b7cfee4b7)) - - -### Bug Fixes - -* chan strip - GUI compressor - delay header was 3 lines ([de6a733](https://github.com/olzzon/sisyfos-audio-controller/commit/de6a73317ef9eec8c140f3a61f09b34dd7dcc105)) -* loading storage with more channels than faders. (e.g. a fader controlling a 5.1 setup) ([93e10ec](https://github.com/olzzon/sisyfos-audio-controller/commit/93e10ec36cc98f3592b6fb10674ab2e8ee64544d)) -* Midas Delay param is between 0 and 1 not ms time ([e535722](https://github.com/olzzon/sisyfos-audio-controller/commit/e53572212d2e80de350e87c375d74fa2b9b61c70)) -* midas protocol missing DELAY_TIME ([12ac11c](https://github.com/olzzon/sisyfos-audio-controller/commit/12ac11c916096b7e7df3726f3319c04642aab018)) -* Type - Midas - fromMixer didn´t have the correct params ([87540f3](https://github.com/olzzon/sisyfos-audio-controller/commit/87540f3515305ad5c2f84349aa8f2df17cecbe2c)) - -## [2.6.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.5.0...v2.6.0) (2020-01-30) - - -### Features - -* QL1 receive fader state working ([d434dd3](https://github.com/olzzon/sisyfos-audio-controller/commit/d434dd32ed89a05ef351f5ac5a2ae0ed7bcf5f8c)) -* QlCl - added mute support FROM Sisyfos ([8793170](https://github.com/olzzon/sisyfos-audio-controller/commit/8793170bba09cec80376531d5b13525fe7f39383)) -* yamaha QL - gain out command moved to protocol instead of hardwired in qlclconnection.ts ([e96f902](https://github.com/olzzon/sisyfos-audio-controller/commit/e96f9026dafb14df48caa2ce1deb8d825d23d14a)) -* Yamaha QL - use Winston logging instead of console.log ([d856e26](https://github.com/olzzon/sisyfos-audio-controller/commit/d856e26432e5ca9289e7fab448ef0d0cb3be9499)) -* yamaha QL1 - get MUTE state (on-off) from mixer ([ce021e9](https://github.com/olzzon/sisyfos-audio-controller/commit/ce021e9e3b5dce95e1eaba6ab2a50fb071705932)) -* yamaha qlcl - inital req of fader levels. - split buffers - 2 byte channel message ([f462841](https://github.com/olzzon/sisyfos-audio-controller/commit/f4628411784c9fb47d3c7349db8d43afe436c65a)) - -## [2.5.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.4.0...v2.5.0) (2020-01-29) - - -### Features - -* CasparCGconnection.ts winston logger support ([4e0a7f0](https://github.com/olzzon/sisyfos-audio-controller/commit/4e0a7f055c3645eead11e567e28cc1c1e30f0858)) -* CCG channelsettings emit action for selecting new channel inputs. ([6f807cd](https://github.com/olzzon/sisyfos-audio-controller/commit/6f807cdda018513fd20418e55e587a4e844140e1)) -* CCG v2 show- PFL in settings replaces CUE NEXT ([9a24def](https://github.com/olzzon/sisyfos-audio-controller/commit/9a24defa5060853656ac46e54d992945bd32d9d8)) -* ccg-v2 - move config files to storage folder. ([53bd70e](https://github.com/olzzon/sisyfos-audio-controller/commit/53bd70e06d76d292cf84c94ff78165cbad25e055)) -* check geometry file for undefined ([b15fbb1](https://github.com/olzzon/sisyfos-audio-controller/commit/b15fbb15f2e02cea8a9ff5896b56ea43db16e151)) -* disable settings in browser by adding localhost:1176/?settings=0 ([f2dc03f](https://github.com/olzzon/sisyfos-audio-controller/commit/f2dc03f77ece5d2522ce54a4f7bb0370153fff8b)) -* load CasparCG settings from Storage menu ([c4e55e6](https://github.com/olzzon/sisyfos-audio-controller/commit/c4e55e6744d33a927b57f2c0e197f2dbe9c7f858)) -* move CasparCG input settings into channelstrip on left side ([7d20317](https://github.com/olzzon/sisyfos-audio-controller/commit/7d20317614a5bb508e29ebf8cd5ab8287f32803b)) -* only show Load CasparCG in Storage menu if there are any .ccg files ([6cda7c0](https://github.com/olzzon/sisyfos-audio-controller/commit/6cda7c0c8c51dda597542c586f6860e0daa92bf7)) -* Preparing CCG - /inject command so it´s possible pass a command directly from Sofie to Audiomixer. ([cb53eb5](https://github.com/olzzon/sisyfos-audio-controller/commit/cb53eb57ac2a322779b3bdecd95be040ea8e1b1e)) -* remove close button in CCG input settings window ([d61dab7](https://github.com/olzzon/sisyfos-audio-controller/commit/d61dab73f52a522e6edd60106f8f714c0db2d50b)) -* remove filehandling from mixerprotocol, include default example ([7918b05](https://github.com/olzzon/sisyfos-audio-controller/commit/7918b0573dd500c858f5e598fb50e373976f4d8e)) -* rename Storage menu to "STORAGE" ([ee917a2](https://github.com/olzzon/sisyfos-audio-controller/commit/ee917a2f9e50a62dba862aa00b609a480df95d7e)) -* set new CasparCG config from Storage Menu is working. ([7eab0b9](https://github.com/olzzon/sisyfos-audio-controller/commit/7eab0b90cc218636a41ffa2c7598661076cebc48)) -* set seperate loglevel for console with loggerConsoleLevel='verbose' updated in Readme.md ([beba900](https://github.com/olzzon/sisyfos-audio-controller/commit/beba90053efcf5c6efe8144ba07f1e7e1e66c17c)) - - -### Bug Fixes - -* GUI crash for reference to fader label, on fader thats not defined. ([9bc4df7](https://github.com/olzzon/sisyfos-audio-controller/commit/9bc4df7f6f4c2753cb0c3933245a1aec9025ba21)) -* zero indicator on faders was off after new design ([78f48b5](https://github.com/olzzon/sisyfos-audio-controller/commit/78f48b5942a47a4393e490d6fadd0fa1fb558471)) - -## [2.4.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.3.3...v2.4.0) (2020-01-23) - - -### Features - -* added Low-mid to get 4-band eq instead of 3-band eq ([59542a8](https://github.com/olzzon/sisyfos-audio-controller/commit/59542a83c1ca889696efe29fb4bc0d958567e77b)) -* chan strip zero indicators on eq, comp and monitor mix ([b9ec40e](https://github.com/olzzon/sisyfos-audio-controller/commit/b9ec40e16a2d6ff4c23fd457ff5a6ec4a9f73b87)) -* channel name in header of monitor mix minus ([99c0207](https://github.com/olzzon/sisyfos-audio-controller/commit/99c020743b641209423b924f042c6619c170321e)) -* get eq & comp state from Midas/Behringer X32 - both inital and realtime ([86bd216](https://github.com/olzzon/sisyfos-audio-controller/commit/86bd216d3e2cf4c15e241cdee6445e191f872d7a)) -* individual runtime args for setting log level of kibana and of local log file. ([e978093](https://github.com/olzzon/sisyfos-audio-controller/commit/e978093cae71699393493426b28d5aac450741ae)) -* Midas/Behringer OSC get inital Aux state from mixer ([7bb0741](https://github.com/olzzon/sisyfos-audio-controller/commit/7bb0741c2833274081d6f110d2b56876bcf5c33b)) -* move ch strip to left side ([89756b9](https://github.com/olzzon/sisyfos-audio-controller/commit/89756b9f39d9ec6715a8eac284690d977fa9e31a)) - - -### Bug Fixes - -* Ardour ping mixewr command didn´t have osc data type ([b84e965](https://github.com/olzzon/sisyfos-audio-controller/commit/b84e965abf679d512eb7333543555485ec84123c)) -* channel-body css didn´t set heigth ([653def0](https://github.com/olzzon/sisyfos-audio-controller/commit/653def0d90f25210a61830aa0ef5f7b517bf0b2f)) -* delay initial state commands to avoid overload of OSC commands to Midas ([443325f](https://github.com/olzzon/sisyfos-audio-controller/commit/443325fc2179b6053271c92548ad64270b61f044)) -* Recived Midas Ratio has value from 0 to 11 and not 0 to 1 ([40afcc5](https://github.com/olzzon/sisyfos-audio-controller/commit/40afcc55d826c0f731f4c64e1f5698b167f0b4aa)) -* typo - dispatch obj with level: instead of label: ([e84abaa](https://github.com/olzzon/sisyfos-audio-controller/commit/e84abaa71671e8d77f0b47a7d6a459fa682717ab)) -* typo - don´t revert dispatch label from level: to label: ([974bec2](https://github.com/olzzon/sisyfos-audio-controller/commit/974bec262d84179a2c3893f979e2ebcdb9f1b715)) -* use .loMid value when updating loMid ([9c61686](https://github.com/olzzon/sisyfos-audio-controller/commit/9c61686a00385076a5764ff20249db50007e3a6d)) - -### [2.3.3](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.3.2...v2.3.3) (2020-01-15) - - -### Bug Fixes - -* rename Label Monitor Mix to: "{FaderName} Monitor Mix Minus" ([d99a67b](https://github.com/olzzon/sisyfos-audio-controller/commit/d99a67b8499f3d21c14047a5ff612b684287ad0e)) -* update Auxlevel on mixer on changes ([08b832e](https://github.com/olzzon/sisyfos-audio-controller/commit/08b832eba9ac81c1a74e2de9b354103d05247b52)) - -### [2.3.2](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.3.1...v2.3.2) (2020-01-04) - -### [2.3.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.3.0...v2.3.1) (2020-01-01) - - -### Bug Fixes - -* CI build errors ([d98475f](https://github.com/olzzon/sisyfos-audio-controller/commit/d98475f6b07381504c626f24394b4dbdacffd668)) -* create storage folder if not exists when trying to store settings for the first time ([41dcb09](https://github.com/olzzon/sisyfos-audio-controller/commit/41dcb09236e3768daa19fe64ce70499e769a0e1e)) -* do not use winston logger in contants files as they´re also used on client side ([fb2d847](https://github.com/olzzon/sisyfos-audio-controller/commit/fb2d84756d7330dfdf799f1269793d012ed0a195)) -* remove settings and default.shot from storage folder ([1c63eb2](https://github.com/olzzon/sisyfos-audio-controller/commit/1c63eb21933ce7414a405393b4c0564c80aace6f)) -* remove settings.json from server folder ([3229936](https://github.com/olzzon/sisyfos-audio-controller/commit/3229936a48c39765103204235a40935d92cb07e1)) - -## [2.3.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.2.0...v2.3.0) (2019-12-21) - - -### Features - -* Ignore Automation implemented. A "MANUAL" button added in GUI so a fader can ignore commands from Automation ([1399711](https://github.com/olzzon/sisyfos-audio-controller/commit/1399711d9b1558702c5c305dc45b09fe82b2ea48)) - - -### Bug Fixes - -* assign aux to fader use auxIndex instead of channel ([a9e3232](https://github.com/olzzon/sisyfos-audio-controller/commit/a9e3232b6a3fdeed9a3729aa7b09a1628931010d)) -* avoid clearing meters when setting full state of faders ([cce69f5](https://github.com/olzzon/sisyfos-audio-controller/commit/cce69f5c6da2b8b946f76f49b1f60ec9dbe0a501)) -* double code in AutomationConnection (had double check for X_MIX, Fade_to_black and visible) ([ff8af54](https://github.com/olzzon/sisyfos-audio-controller/commit/ff8af54c81bc4cff3ad8a8c04364e2d76a01ce52)) -* OscMixerConnection - compare whole command length ([876b367](https://github.com/olzzon/sisyfos-audio-controller/commit/876b3679ae772d6f3ebc2ddff608220c48beeeee)) -* Update GUI when state of muteOn and voOn is changed ([52bf3da](https://github.com/olzzon/sisyfos-audio-controller/commit/52bf3da1aa2ad2aa63ec2b03cc7fc6a4a0c97642)) - -## [2.2.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.1.0...v2.2.0) (2019-12-18) - - -### Features - -* mixer online - will restart server. ([fea6b24](https://github.com/olzzon/sisyfos-audio-controller/commit/fea6b24f897ee4a9e0e101fc45b5d1b92ed4227d)) - - -### Bug Fixes - -* move storage to "storage" folder, to avoid docker conflicts ([7323ed9](https://github.com/olzzon/sisyfos-audio-controller/commit/7323ed9675b57dbff528a54dad93271099bda14d)) - -## 2.1.0 (2019-12-18) - - -### Features - -* add channel settings UI ([8351cb0](https://github.com/olzzon/sisyfos-audio-controller/commit/8351cb05ffebf6aa2aa491023e3a5d2bd9b11287)) -* added protocol latency in settings. So setting "fadeActive" to false waits until last response from protocol. ([6d949ed](https://github.com/olzzon/sisyfos-audio-controller/commit/6d949edb988f741d63e91c0a34241c3eb8ab4cee)) -* Ardour adding meter support ([1864e3e](https://github.com/olzzon/sisyfos-audio-controller/commit/1864e3e88da2cfaa4db2d0c8e7332baef05591be)) -* Ardour meter support meter not meters ([9802ff5](https://github.com/olzzon/sisyfos-audio-controller/commit/9802ff5314b872fe6e5539ecdd78fe6fc9096128)) -* Ardour support - added channel name from mixer ([d767318](https://github.com/olzzon/sisyfos-audio-controller/commit/d76731868de78220070f70348cffc065083856dc)) -* Ardour support meter calimbration (loosely set) ([eb01418](https://github.com/olzzon/sisyfos-audio-controller/commit/eb014183fdf8bc3ab3bd66bf390fbf4959e66dcc)) -* CasparCG support as audio mixer ([#35](https://github.com/olzzon/sisyfos-audio-controller/issues/35)) ([d47cf5b](https://github.com/olzzon/sisyfos-audio-controller/commit/d47cf5bb018d6f7cab8b6d6b806a84d1c60511a5)) -* change VU meter rendering to canvas-based ([ee829d7](https://github.com/olzzon/sisyfos-audio-controller/commit/ee829d7960a0849826c2e90b459fcd760836b5a0)) -* Channel labels - protocol now support setting labels on mixer ([751b812](https://github.com/olzzon/sisyfos-audio-controller/commit/751b812d407d622b4fbd4d38f07ad167e3e2daac)) -* ChannelType added to IChannel in channelsReducer so each channel can reference to a channel type ([995b99e](https://github.com/olzzon/sisyfos-audio-controller/commit/995b99e26da34a20a5bf1663a504f14554cc2e51)) -* ChannelTypes - Channel color and label injected from mixerprotocol ([9552320](https://github.com/olzzon/sisyfos-audio-controller/commit/9552320e068008184cfb029fa8f5e226ebfa7ed3)) -* channelTypes - Ember+ level and gain implemented ([5f2752f](https://github.com/olzzon/sisyfos-audio-controller/commit/5f2752fe0f7aa0eda7ce7f98fe32a32f0bc63dc4)) -* ChannelTypes - mixerProtocol actions is changed from string to Array ([5448e7a](https://github.com/olzzon/sisyfos-audio-controller/commit/5448e7ab273c0ad5f5b11e5f6326c77058e3fb7d)) -* ChannelTypes - preparing settings for numberOfChannelTypes ([ef1a9ba](https://github.com/olzzon/sisyfos-audio-controller/commit/ef1a9baa9f6e98255ab95fec560b70b0dd1c230d)) -* channeltypes- OscMixerConnection send level to the different channelTypes ([fd6d9ef](https://github.com/olzzon/sisyfos-audio-controller/commit/fd6d9ef7f62e40aa9bdd383dad56d4efe3479c41)) -* ChannelTypes: Changed numberOfChannels to numberOfChannelsInType (current ussage is [0]) ([114538d](https://github.com/olzzon/sisyfos-audio-controller/commit/114538d4800b47150e86078dbf8d2e74767d6850)) -* DMXIS - set label from Automation to DMXIS ([ac4038f](https://github.com/olzzon/sisyfos-audio-controller/commit/ac4038f8c831f59eb2fd58f3a730b5d9ccdb8fef)) -* Ember - trying to figure out invokeFunction ([0210ed1](https://github.com/olzzon/sisyfos-audio-controller/commit/0210ed1052c988418e0ce6eeeb35caf6b19c96d6)) -* Ember - trying to figure out setValue (right now it only resets the value) ([1e27c53](https://github.com/olzzon/sisyfos-audio-controller/commit/1e27c53b2a3f637230079d9156c632791226cee6)) -* Ember Protocol - Subscribe label changes ([5b83282](https://github.com/olzzon/sisyfos-audio-controller/commit/5b83282f9d4ae7a30e68f5474ce52d1fedf3bde3)) -* Ember Studer support - Added Vista 1 - Vista 5 - Vista 9 ([d602daa](https://github.com/olzzon/sisyfos-audio-controller/commit/d602daac47c9ff01f656de47cff8986fa1cdc1d2)) -* fader -> channel routing. implementing faders reducer in channel component ([85a1705](https://github.com/olzzon/sisyfos-audio-controller/commit/85a1705bb6f0179ca49120305c06c194edfd8b33)) -* Fader-Channel routing - initial datastructure for abstration of fader - channel ([93af7b1](https://github.com/olzzon/sisyfos-audio-controller/commit/93af7b14404b4d4ee812c4572f7bb89d16969d97)) -* Hui Remote - change of fader from Sisyfos to HUI working. ([c6f07a9](https://github.com/olzzon/sisyfos-audio-controller/commit/c6f07a92425f93cd3347e8f242309c5e820d4210)) -* Hui remote - Remote solo button toggles Sisyfos PFL on/off ([2587ff8](https://github.com/olzzon/sisyfos-audio-controller/commit/2587ff80263e4e842142b790171c61c5638e5d91)) -* hui remote - Select button togles sisyfos PGM on/off ([3ad29b5](https://github.com/olzzon/sisyfos-audio-controller/commit/3ad29b59024a7bf243d50f22837578663e817712)) -* HUI remote - Status of SELECT and SOLO button led updates when button is pressed ([bd40f81](https://github.com/olzzon/sisyfos-audio-controller/commit/bd40f812a0c7ba41b78a98e8e5f965bfac99018a)) -* hui remote - update hui if mixer faders are changed by mixer ([8bb116a](https://github.com/olzzon/sisyfos-audio-controller/commit/8bb116a9a28d0e080e8b7fb1869066f571b9c1e8)) -* HUI-remote - Button led reflects Sisyfos state ([df620b9](https://github.com/olzzon/sisyfos-audio-controller/commit/df620b93e36f136a6332f2efb7c7b80238d2a853)) -* implement aux configuration in Storage load/save ([7e01f2a](https://github.com/olzzon/sisyfos-audio-controller/commit/7e01f2a153a1d2e7e76db9c00f3c067718a62928)) -* Implemented "zero" indicator on Faders ([6ee7029](https://github.com/olzzon/sisyfos-audio-controller/commit/6ee702921f55484f021dcd7330b6caff46f70b10)) -* Initial support for Ardour ([4512985](https://github.com/olzzon/sisyfos-audio-controller/commit/4512985b01af5b8be70fc5a344e668a2ed0b83dd)) -* Lawo R3LAYVRX4 - NOT WORKING YET ([ffccf79](https://github.com/olzzon/sisyfos-audio-controller/commit/ffccf792c37d3d0604205787c3898e2f08abd0ce)) -* Let an automation system ping sisyfos, to verify connectivity status. ([b3a1a46](https://github.com/olzzon/sisyfos-audio-controller/commit/b3a1a4665076958aacc6004c2d35b648d66a1784)) -* Midi Mixer Protocol - settings select Midi input and output port, when a MIDI mixer protocol is selected ([3dd2567](https://github.com/olzzon/sisyfos-audio-controller/commit/3dd2567660e2254bb6ad9a7dddd9dcdc1dd2c194)) -* MidiMixerConnection - using type from protocol ([96576f4](https://github.com/olzzon/sisyfos-audio-controller/commit/96576f4a18dfb1c054e48778be1a06d87839659d)) -* MixerProtocol prepared ChannelType based structure. ([bd05bb5](https://github.com/olzzon/sisyfos-audio-controller/commit/bd05bb5492e10e834a3e2e6560dbae2e6a735fe4)) -* New ChannelType - channelType and channelIndexType implemented in channelReducer and snapShot state ([4082795](https://github.com/olzzon/sisyfos-audio-controller/commit/4082795b834ab71cd0fac940e0b4e5b495840531)) -* new ChannelTypes - settings number of each channeltypes ([b733529](https://github.com/olzzon/sisyfos-audio-controller/commit/b73352959b48bcaed5337b68f2b8fa88261d22e7)) -* Protocol for DMXIS lightcontrol ([0c9cb1f](https://github.com/olzzon/sisyfos-audio-controller/commit/0c9cb1f41ec029535c501a82e5cb3d967852482e)) -* Reaper Master Protocol DCA support ([f301dcd](https://github.com/olzzon/sisyfos-audio-controller/commit/f301dcd05828b82b4f805744dde13f9c1e72a4ad)) -* remote midi connetion - prefare PFL ([ffbde02](https://github.com/olzzon/sisyfos-audio-controller/commit/ffbde02ca822cbca644fc4096333a7a5ed8b8ab3)) -* Remote midi controÃller - update mixer when recieving level change from remote ([ccf95b3](https://github.com/olzzon/sisyfos-audio-controller/commit/ccf95b3b490988e6eff8f600286ac92b85f08ab4)) -* Remote Midi Control - working on datastructure ([b15542f](https://github.com/olzzon/sisyfos-audio-controller/commit/b15542f7ae08b1422fd22576acc8ba78958a2127)) -* Remote midi controller - change generic midi remote contrioller to a dedicated HUI controller ([73e4372](https://github.com/olzzon/sisyfos-audio-controller/commit/73e4372a1bdb0de9204aee41edd0c053df3f61ec)) -* Remote Midi Controller - connect to selected midiports from settings ([1eb4500](https://github.com/olzzon/sisyfos-audio-controller/commit/1eb45001f43579060341120bee29740da48c5423)) -* Remote midi controller - Convert Midi controller levels to audio mixer levels ([ddde5fc](https://github.com/olzzon/sisyfos-audio-controller/commit/ddde5fcd109583caa7b255a8fd6cabd600295945)) -* Remote Midi controller Adding support for play, stop, pitch bend types in remote protocol. instead of just ctrl-change ([f043c97](https://github.com/olzzon/sisyfos-audio-controller/commit/f043c974a1d4cfc6387d926cfbf7a5b4fe847eac)) -* Remote MidiControl - Added Faderlevel ([20a9548](https://github.com/olzzon/sisyfos-audio-controller/commit/20a954834eb05c6f1f401500cae7af805f095f10)) -* Remote MidiController - mixerConnection to be used for updating mixer status ([8f404a5](https://github.com/olzzon/sisyfos-audio-controller/commit/8f404a50f6821d41faeead94e5774ab3bab9d3fa)) -* Remote MidiController - preparing value conversion from mixer min-max to remote min-max ([e4764b9](https://github.com/olzzon/sisyfos-audio-controller/commit/e4764b97a252d5990849a1dc2f6b7b1a13028cb0)) -* Remote midicontroller - Recieve messages working ([d60ad72](https://github.com/olzzon/sisyfos-audio-controller/commit/d60ad72cc2d71354ad1712afbc9a82309d53477c)) -* Remote Midicontroller - Settings added pull down menus for selecting midiports in and out for controller ([6e754cd](https://github.com/olzzon/sisyfos-audio-controller/commit/6e754cd93332413873f43593f739594bfb54789a)) -* remote-hui fader from hui to sisyfos working ([97e6faa](https://github.com/olzzon/sisyfos-audio-controller/commit/97e6faa18d001c588cb7b35f899a3affb2f90794)) -* RemoteFader support - preparing support ([5ed8364](https://github.com/olzzon/sisyfos-audio-controller/commit/5ed83643e250f544cbf8c5323a746d0516ea6b31)) -* Set channel label on mixer from Sisyfos and from Automation ([35fbc34](https://github.com/olzzon/sisyfos-audio-controller/commit/35fbc3485c521d92796bcfe5016b7c3081ad0eae)) -* Studer Vista - initial support ([ea054e3](https://github.com/olzzon/sisyfos-audio-controller/commit/ea054e3c05225b50deb5cb841082de7b168e83ff)) -* Studer Vista Label support ([fbaf105](https://github.com/olzzon/sisyfos-audio-controller/commit/fbaf10514a9ac2f7d72293a83f7ad578566c54cf)) -* support restarting source producer to change source properties ([ad9c560](https://github.com/olzzon/sisyfos-audio-controller/commit/ad9c560eb3fe848c5031caa079a8914ef2ca23a9)) -* Yamaha QL1 midi support - basic funtionality working ([e7460e2](https://github.com/olzzon/sisyfos-audio-controller/commit/e7460e274a921d67ba0c449b53b931aa8873f2dc)) -* Yamaha QL1 support - created protocol (not functioning yet) ([497db09](https://github.com/olzzon/sisyfos-audio-controller/commit/497db09ed654cb661ade12899a25887305ba22a6)) -* **casparcg:** support VU meters on CCG mixer ([f6a5c4d](https://github.com/olzzon/sisyfos-audio-controller/commit/f6a5c4d59a92d5604715a343dc73cdfbb5228a53)) +### [4.17.1](https://github.com/tv2/sisyfos-audio-controller/compare/v4.17.0...v4.17.1) (2022-03-11) ### Bug Fixes -* /state/full should include showFader status ([c0be854](https://github.com/olzzon/sisyfos-audio-controller/commit/c0be854eafbdb6529f895fa214a8aba339d70e75)) -* as new react-slider module has a z-index of 1, settings pages are changed to a z-index of 2 ([af5a46c](https://github.com/olzzon/sisyfos-audio-controller/commit/af5a46c5c83a03b9ece3d11880b9a50e8fe9a5aa)) -* Automation PST command must update NextAux ([f635362](https://github.com/olzzon/sisyfos-audio-controller/commit/f63536225983f1f8c88550c9c7cb637aebf66e23)) -* Automationprotocol - return address data structure is to.address not to.ip ([75ceb9a](https://github.com/olzzon/sisyfos-audio-controller/commit/75ceb9aacdeda699d72108b7a9109ee5b5a24371)) -* CasparCG protocol min and zero values are used in channelTypes, so they are adjusted accoringly ([be6a5eb](https://github.com/olzzon/sisyfos-audio-controller/commit/be6a5eb814dad27f130ee9caf1d80378e0f669b5)) -* channel - fader abstractions was not correct ([5145b43](https://github.com/olzzon/sisyfos-audio-controller/commit/5145b43d69bd16ad86ab78977d21b0d1ad97b457)) -* Channel had faderChannel as reference instead of ch ([ea877dd](https://github.com/olzzon/sisyfos-audio-controller/commit/ea877dd495bf8c1f9e7b9b0fb9fd5db04fcb146b)) -* checkOscCommand - returned always true ([d502820](https://github.com/olzzon/sisyfos-audio-controller/commit/d50282082340bd53ca82386f8115c8f97038a332)) -* ClassNames in Sttings was there by accident ([c6d29b6](https://github.com/olzzon/sisyfos-audio-controller/commit/c6d29b6c01a77cded8507b232ab78c29842c51f4)) -* Clear protocolDelay timer when aborting old fade ([7801638](https://github.com/olzzon/sisyfos-audio-controller/commit/78016382f7430d723c59128f17dde6257e4562cb)) -* Colors for active faders was missing after converting to react-slider based faders ([15e34f3](https://github.com/olzzon/sisyfos-audio-controller/commit/15e34f3202e6356b5489261f96747a9363b6105a)) -* don´t send faderLeel to mixer, as it reference to multiple channels now. ([a2a1240](https://github.com/olzzon/sisyfos-audio-controller/commit/a2a124037099c83a1b88acf0afff8d6aa8b09a48)) -* Electron nodeIntegration: false - added preload.js - prepare for moving hw related stuff to server side ([2ec903d](https://github.com/olzzon/sisyfos-audio-controller/commit/2ec903d56c133c963a412b8683b1641fd8d99eae)) -* Fade I/O - use channelType min and zero for setting target gain ([6a935c6](https://github.com/olzzon/sisyfos-audio-controller/commit/6a935c6e58344bbe0c473bcb451d1bf7bcf32a65)) -* fadeToBlack - only send commands for channels that are open ([48ed2ae](https://github.com/olzzon/sisyfos-audio-controller/commit/48ed2aef0792fe506fad401ccc8b8f531df4aa88)) -* ipaddress of return message is not to.id but to.address ([b5f3871](https://github.com/olzzon/sisyfos-audio-controller/commit/b5f387167cfb7ea8c61b34b7575ca77d8e4b1f04)) -* Meter align with "zero" ([48f662a](https://github.com/olzzon/sisyfos-audio-controller/commit/48f662a80f7f474c5f27ae82c2e595d356985ae0)) -* Midi - addListener should have channel number and not controlchange number ([aec6ea8](https://github.com/olzzon/sisyfos-audio-controller/commit/aec6ea8b8f030cd2310449e982c23ac1302f4668)) -* Midi HUI remote controller, update new structure fader instead of channel ([c4c9c3b](https://github.com/olzzon/sisyfos-audio-controller/commit/c4c9c3be98915d7a6c2f05afa8e8cfb472445cd5)) -* Midi protocol - update faders when multiple faders are changed ([a8c6da8](https://github.com/olzzon/sisyfos-audio-controller/commit/a8c6da8b121f405ca76633f8facf68f77da7e886)) -* More fader steps in Yamaha QlCl protocol (before it only had 10 steps from 0 to 1) ([a9d81a8](https://github.com/olzzon/sisyfos-audio-controller/commit/a9d81a8ac1ce7b9d20d674bd4da1786236fb9bca)) -* new channelType - emberMixerConnection, subscription used ch instead og channelTypeIndex ([0d630bb](https://github.com/olzzon/sisyfos-audio-controller/commit/0d630bb9bd70b5ef2a27f1a8e1d58469fc1d8a1e)) -* new forked osc.js dependcy, to allow use without rebuilding ([bf8797b](https://github.com/olzzon/sisyfos-audio-controller/commit/bf8797bafdfa6193154b290eb4aeaf17e25cd9fb)) -* numberOfChannels pr. type instead of totalNumberOfChannels ([139b4c1](https://github.com/olzzon/sisyfos-audio-controller/commit/139b4c1a296cea71b3e0565b6c9c80af661f5f2a)) -* only channels of first channelttype was set after reload ([f50296e](https://github.com/olzzon/sisyfos-audio-controller/commit/f50296e57773a8020d63699ee0fad24f8aa27ef8)) -* OSC command had wrong fader Index ([bef73e4](https://github.com/olzzon/sisyfos-audio-controller/commit/bef73e4af204b3cfa86919e13a0300e4bf8766be)) -* OSC protocol - All faders follows when changed on mixer ([b5d9515](https://github.com/olzzon/sisyfos-audio-controller/commit/b5d9515601d55bc963f672360fda6381704a6642)) -* Package.json --asar does not take any arguments ([dcfa901](https://github.com/olzzon/sisyfos-audio-controller/commit/dcfa9011b8926766e6e96f950a101795447bb62b)) -* pass auxIndex to aux level reducer ([a41b987](https://github.com/olzzon/sisyfos-audio-controller/commit/a41b9878e87a1c044548aea049c880be3cdda819)) -* PFL should not mute channel ([3c66960](https://github.com/olzzon/sisyfos-audio-controller/commit/3c669601c848230bd086afcdbe36c1746c297779)) -* pgm off didn´t get a prober fadetime ([1cbf98b](https://github.com/olzzon/sisyfos-audio-controller/commit/1cbf98b4b5cd9b8f77011b11248cf6112c10891f)) -* problem with CCG interface incorrectly understanding decklink device ID ([8889acd](https://github.com/olzzon/sisyfos-audio-controller/commit/8889acd6493f2bd0a37933168ba3ab8a72a74564)) -* QlClMixerConnection bug re huiRemoteConnection ([892bc27](https://github.com/olzzon/sisyfos-audio-controller/commit/892bc27a97956b35def27bb008e250e67df8db94)) -* QlClMixerConnection called hui with wrong argument ([8fbdd1b](https://github.com/olzzon/sisyfos-audio-controller/commit/8fbdd1b3635c8d0f40debb4c2dbd2b73c834fa88)) -* Reaper protocol. Wrong handling of feedback from mixer ([51bd2fb](https://github.com/olzzon/sisyfos-audio-controller/commit/51bd2fb638715670066a17275b17ca3e424cadc7)) -* send state commands back to right ip and expose full state ([3a6f257](https://github.com/olzzon/sisyfos-audio-controller/commit/3a6f257de1de1557e802e2572c4c4bbd64e48b3e)) -* setting menu, added cancel button to reload without saving ([931ddbe](https://github.com/olzzon/sisyfos-audio-controller/commit/931ddbefbe89d42bb3226f2ad913917f9aa77d55)) -* settings - Protocol specific options displayed when protocol is changed (e.g. midi ports when a MIDI based protocol is selected) ([25167d2](https://github.com/olzzon/sisyfos-audio-controller/commit/25167d2bf0cd8a65477eeec2d937e62e5d4c8202)) -* settings and routing menus position: fixed instead of absolute ([591877e](https://github.com/olzzon/sisyfos-audio-controller/commit/591877e73338e36be2c4c957dd0a79b13a2040f3)) -* showMessageBoxSync parsed a null to an optional argument. Now removed ([3f4561f](https://github.com/olzzon/sisyfos-audio-controller/commit/3f4561febd6c1157d0980d3e177445296798e3c1)) -* slider scroll - check for touchscreen ([7331216](https://github.com/olzzon/sisyfos-audio-controller/commit/73312166258c3afd8b4249cc11957bb1968a302b)) -* SSL adjust fader all way to zero ([894a406](https://github.com/olzzon/sisyfos-audio-controller/commit/894a4065894c6b49136294d5b9d999f38b3474f6)) -* SSL check for negative value before converting to Uint8Array ([54edfa3](https://github.com/olzzon/sisyfos-audio-controller/commit/54edfa33c1f6e2697aad15993c073c1bd3bc7192)) -* SSL protocol did not receive initial state from desk. ([9009d46](https://github.com/olzzon/sisyfos-audio-controller/commit/9009d46314c4da6acbe96308b2d3a2e81815a50d)) -* StuderVistaEmber file added ([bc4dcb3](https://github.com/olzzon/sisyfos-audio-controller/commit/bc4dcb39aa863577dbc7db05cf4d45aac33335af)) -* toggleShowChannelStrip toggle between channels ([22abc5f](https://github.com/olzzon/sisyfos-audio-controller/commit/22abc5faaa51cac5adc6be378ab05f3b8c61d607)) -* typeof declarationas ([d627950](https://github.com/olzzon/sisyfos-audio-controller/commit/d62795067bd29d7af98602291ff035569e19eda0)) -* undo emptMiserMessage() as it didnt work inside object ([5da0bea](https://github.com/olzzon/sisyfos-audio-controller/commit/5da0bea9433e78e0f909f37ae5bb4b6296d1832f)) -* update HUI remote fader, when level are changed from the mixer ([b762d5f](https://github.com/olzzon/sisyfos-audio-controller/commit/b762d5f6c9c3e85409be17fd0b580d76322a6b06)) -* upload preload.js file after it was moved ([b87c859](https://github.com/olzzon/sisyfos-audio-controller/commit/b87c859525ee22c7215857e829786dd10b2d6d47)) -* Webpack build - removed Babili and css mini extract plugins ([8ebd664](https://github.com/olzzon/sisyfos-audio-controller/commit/8ebd6649503c6626129c7c362545e06080fe64b3)) -* when receiving fader update from mixer, responded level should be faderlevel not outgain ([0fd1bd5](https://github.com/olzzon/sisyfos-audio-controller/commit/0fd1bd53b0291ab7546c1cb228d52c5f9d339783)) -* z-index was added to settings.css (as module react-slider has a z-index=1) ([b666157](https://github.com/olzzon/sisyfos-audio-controller/commit/b666157b68479dba46a74dcf9cd8de2082fb1d9c)) -* **casparCG:** ensure that the filePath is a string ([248f863](https://github.com/olzzon/sisyfos-audio-controller/commit/248f86374a2b4aafef5cd41f7dc3291f00b3322e)) -* **casparcg:** resolve an issue with PFL ([caf4946](https://github.com/olzzon/sisyfos-audio-controller/commit/caf494634876fc51ce895a377f2d8a735b3c3641)) -* added file for last commit ([6197f2b](https://github.com/olzzon/sisyfos-audio-controller/commit/6197f2b35113ae9b8886f1a27ff04a2e1131fcee)) -* added midiReceiveType variable ([abc1c2a](https://github.com/olzzon/sisyfos-audio-controller/commit/abc1c2a0ec00fa0476ac744f877a063614d2ff28)) -* adding .ts files for last commit ([85cb336](https://github.com/olzzon/sisyfos-audio-controller/commit/85cb33641578aae5a8f3d5c523b4816ba2df2ee4)) -* App -> passed an unused argument to MidiRemoteConnection ([386d496](https://github.com/olzzon/sisyfos-audio-controller/commit/386d4967c42cf8146c3bea1b267050192f6a2e16)) -* AutomationConnection, OSC server could only receive local connections. IP changed to 0.0.0.0 ([ceb4d2f](https://github.com/olzzon/sisyfos-audio-controller/commit/ceb4d2f523f1173941d1172c6a847ab49a7e0031)) -* Background on the whole mixer should be black ([e3e1583](https://github.com/olzzon/sisyfos-audio-controller/commit/e3e1583577e7cfbd9e7a4c16ac73e3961b212706)) -* behringer and midas vu-meter import was removed ([d557479](https://github.com/olzzon/sisyfos-audio-controller/commit/d55747927f75e1c687d8be8634629a2b7471a68d)) -* bouldn´ build app. Babel didn´t have preset-env installed ([58c573b](https://github.com/olzzon/sisyfos-audio-controller/commit/58c573b224d96f6c4b18451d63fbd6bba20768f5)) -* changed value var to any as it can be a string or a number ([cb975a9](https://github.com/olzzon/sisyfos-audio-controller/commit/cb975a9dbbbe6d7328076a45b0b456bf179effe5)) -* check for placement of {channel} in OSC commands ([67bab5b](https://github.com/olzzon/sisyfos-audio-controller/commit/67bab5b63316c4e93ed810a6665dadd2befd8a19)) -* checkOSC command, if {channel} was last parameter in command it returned false ([c959bf0](https://github.com/olzzon/sisyfos-audio-controller/commit/c959bf0d3337357bab0f14b5e6dedde593529e79)) -* CI added environment in test ([11ce0ee](https://github.com/olzzon/sisyfos-audio-controller/commit/11ce0ee8680600164ad08856c6b2ce9560263f23)) -* CI comment out whole test ([f3eb9f2](https://github.com/olzzon/sisyfos-audio-controller/commit/f3eb9f26a84ae0da465cfc12e6c5b48c29c47391)) -* CI only test build ([7905a6b](https://github.com/olzzon/sisyfos-audio-controller/commit/7905a6bccd13bd72b3ccb53621484a8472a56371)) -* CI only test build ([0c178b5](https://github.com/olzzon/sisyfos-audio-controller/commit/0c178b5fe5f91da24a420d92dd34b02416cbf8a5)) -* defaultChannelReducerState pushed to undefined array. ([f829191](https://github.com/olzzon/sisyfos-audio-controller/commit/f8291913aae5f156f2608632d5096654279a1419)) -* enable/disable HuiRemoteController in settings ([39e0824](https://github.com/olzzon/sisyfos-audio-controller/commit/39e08249152790a1ba4b1635acdf9775c36db29a)) -* Fade to excact target val (and not nearby) ([feafa5e](https://github.com/olzzon/sisyfos-audio-controller/commit/feafa5eacba96008f755199f1f719c187ed70882)) -* fadeOut didn´t end if fader was exactly === min ([2868a62](https://github.com/olzzon/sisyfos-audio-controller/commit/2868a629f7df645e0953440b81353cb0b9e8f7ca)) -* Fadi In/out when "master" mode didn´t turn down when PGM was on. ([2313f0d](https://github.com/olzzon/sisyfos-audio-controller/commit/2313f0d12bd9ca5628ce4567afab41a684babd33)) -* forgot to add new files in new location on last commit. ([b6e24ab](https://github.com/olzzon/sisyfos-audio-controller/commit/b6e24abf4a873023cd1ff03ea1270cefc7c529e4)) -* GrpFader.css - grpFader-pst-button.on show inactive color and off show active ([f8b3dc9](https://github.com/olzzon/sisyfos-audio-controller/commit/f8b3dc9a3e5bd8a9f66747c0654094fc090fc9a1)) -* GrpFader.tsx should not be a PurComponent when using shouldCompenentUpdate ([77ca0e3](https://github.com/olzzon/sisyfos-audio-controller/commit/77ca0e3ed9afa44e5692dbc380bfa566ecba30ce)) -* HUI remote - change test order of midi message so it checks for fader change before test for button ([38a71f7](https://github.com/olzzon/sisyfos-audio-controller/commit/38a71f7ea357b0355eae79c06434bf607a4f39b8)) -* HUI remote - only update HUI if connected ([ed855c0](https://github.com/olzzon/sisyfos-audio-controller/commit/ed855c0510885a2bf47b76177377bd8c2feea4f8)) -* Index offset when calling snap from automation ([28906d2](https://github.com/olzzon/sisyfos-audio-controller/commit/28906d273ce143b9a48f200401ded7d375f2b472)) -* Individual fadetime, use fadeTime var instead of default value in Fades ([dbf1f9b](https://github.com/olzzon/sisyfos-audio-controller/commit/dbf1f9bd81b00cd2e819dc7047288a1693f8fc09)) -* linux and win builds, no icon ([512b361](https://github.com/olzzon/sisyfos-audio-controller/commit/512b361e2894ce2193170086a5014eb9f57b126c)) -* Meters didn´t work on behringer and midas after renaming. ([b090182](https://github.com/olzzon/sisyfos-audio-controller/commit/b0901829b08f59d3466cceddfe75d85419c3e6e5)) -* missing /ch/1/visible ([f16674a](https://github.com/olzzon/sisyfos-audio-controller/commit/f16674ac4245313a1fb0d577f31ef3ac7e810ec8)) -* MixerConnection - Fade dispatch resolution didn´t iterate ([4cf207f](https://github.com/olzzon/sisyfos-audio-controller/commit/4cf207f70d7f108e82829620eebfcc6bd57dfcbc)) -* moved channelTypes to IMixerProtocolGeneric as it´s need when initialising the App for total number of channels ([33400f3](https://github.com/olzzon/sisyfos-audio-controller/commit/33400f36899e95ab9d5f96dbc43f49269f2be369)) -* offset between channel and array ([8e0fe91](https://github.com/olzzon/sisyfos-audio-controller/commit/8e0fe91e2b0d2f10713795ba0ea98743651717e8)) -* Only rerender when new state in store. Bug: snapOn is an array and forces a re-render everytime the redux runs it´s reducer ([98e48a1](https://github.com/olzzon/sisyfos-audio-controller/commit/98e48a164eadb878127a8b1e1574ddae416125b9)) -* PFL pass complete OSC command for turning on and of PFL ([acb3108](https://github.com/olzzon/sisyfos-audio-controller/commit/acb3108c89ca713ff55d92b8bca33d0f716f80e8)) -* Protocol cleanup - removed references to deleted protocols ([d01d3ca](https://github.com/olzzon/sisyfos-audio-controller/commit/d01d3ca792b5a6cf5f88c8a2ea7f1141fa2d941f)) -* Protocol cleanup, removed protocols deleted in import ([9afeded](https://github.com/olzzon/sisyfos-audio-controller/commit/9afeded2e30a03326d2b73c96a8344a09887c8d2)) -* re-render grp fader ([738895c](https://github.com/olzzon/sisyfos-audio-controller/commit/738895c6077dbe821126a947d427316348e9b411)) -* refered to props store instead of windows store ([f022d79](https://github.com/olzzon/sisyfos-audio-controller/commit/f022d79cac9b9e3b7a0c1406ae424328335f2c0a)) -* removed double background-color assignment in Channel.css ([9213f50](https://github.com/olzzon/sisyfos-audio-controller/commit/9213f50a9527e4dd9097f53311e3b9ce5b65c2e3)) -* Rerender when clicking on a snap button. props state is now each elements value and not the object of the element ([fbe8dcd](https://github.com/olzzon/sisyfos-audio-controller/commit/fbe8dcd837b81523e74093443aec4c955b9173c3)) -* SET_OUTPUT_LEVEL didn´t have a return so VU was set. ([0d14869](https://github.com/olzzon/sisyfos-audio-controller/commit/0d14869bd7ffea5541c2abc09ed0548714fd22e6)) -* slow crossfade when take 32channels. dispatchTrigger added, so store only updates every 5 times the OSC fader is updated. ([f70061d](https://github.com/olzzon/sisyfos-audio-controller/commit/f70061dc8052675121abefe3f6c2ee0f60dce7ef)) -* small type fixes ([d6d673f](https://github.com/olzzon/sisyfos-audio-controller/commit/d6d673ff208ee9a5ef2a428c1a1da16623bc3c58)) -* toggling a snap on a channel didn´t update the gui. its now checked in shouldComponentUpdate ([face0e3](https://github.com/olzzon/sisyfos-audio-controller/commit/face0e3288f1028031041112d242191b4ebbaa4c)) -* turned on channel instead of GrpFader ([56868af](https://github.com/olzzon/sisyfos-audio-controller/commit/56868af2840a6e7c19cf95c7fedc6104f4ddced8)) -* type - assigned true to pflOn instead of comparing in if ( = instead of === ) ([83e0cba](https://github.com/olzzon/sisyfos-audio-controller/commit/83e0cbac1e4c950777e28468a579b8ea8a77485f)) -* type used = instead of === ([c350927](https://github.com/olzzon/sisyfos-audio-controller/commit/c35092755abbde9ea6e586ca67b42bca9860417e)) -* TYPO ([e2f761a](https://github.com/olzzon/sisyfos-audio-controller/commit/e2f761a9db7e9b1bb1224f6ab5e41db949987133)) -* Update gain level in redux store so a change of volume while fading doesn´t jump back to gain from before last fade start ([68ae069](https://github.com/olzzon/sisyfos-audio-controller/commit/68ae0698bfd9c817286dfd158f4be8d5ecf4f87a)) -* Update webpack.build for ts with babel. ([70e2437](https://github.com/olzzon/sisyfos-audio-controller/commit/70e2437d870f699e03e79191119de4e4e6314a3c)) -* When an channelsetting is on and new protocol are selected that haven´t implementee channelsettings, the settings wouldn´t go away after reload. ([82373dd](https://github.com/olzzon/sisyfos-audio-controller/commit/82373dd0600e2fc21438f59af4b5461264dd048e)) -* When running as "master" volume did not lower when pgm on. ([069b4b0](https://github.com/olzzon/sisyfos-audio-controller/commit/069b4b0ab7cf81ffb73618b2a1bdd26830b28057)) -* window size on open, element types in Settings ([cdb2430](https://github.com/olzzon/sisyfos-audio-controller/commit/cdb2430b018db720f829c8c702dcdb5e1c07cbb6)) -* yarn build - did not build as || was used instead of && ([48930e8](https://github.com/olzzon/sisyfos-audio-controller/commit/48930e8d64bea302d8bdf40413faed675c3bbeb6)) +* Added check if fails when writing to storage. ([df7da74](https://github.com/tv2/sisyfos-audio-controller/commit/df7da74fead132525312619dc11ac7b5f47b3a0f)) +* Client bugs + moved server code to src folder. ([79e639d](https://github.com/tv2/sisyfos-audio-controller/commit/79e639da2429477350f6c5b7e53a0ddf9c43ccc4)) +* Converted the last require() to import. ([1879b7d](https://github.com/tv2/sisyfos-audio-controller/commit/1879b7deefb4a8d21c4a3e7f2264e119ee7bcd07)) +* Downgraded nouislider due to breaking changes in previous upgrade. ([7229e2c](https://github.com/tv2/sisyfos-audio-controller/commit/7229e2c610545d70fcf2b9f6b0367d249406f54e)) +* Moved client code to src folder + server serving correct static files. ([cd0fdfa](https://github.com/tv2/sisyfos-audio-controller/commit/cd0fdfa5bf282fa5fd85d5f09abe3271f8ac8fe3)) +* remove recalcAssignedChannels from hot path ([c5bf42b](https://github.com/tv2/sisyfos-audio-controller/commit/c5bf42b7b04f9d854a656dff0f59fdf936e95ea1)) +* Updated github actions prod workflow to build desktop. ([31df0a0](https://github.com/tv2/sisyfos-audio-controller/commit/31df0a050c1e9cf22f74c3bade8c9583c1878e9b)) +* Updated snapshotHandler and SettingsStorage to use absolute path. ([fd559ef](https://github.com/tv2/sisyfos-audio-controller/commit/fd559efa40dce34d8f638de66c0223903e875dc8)) +* Use 2 step dockerfile. ([d9be891](https://github.com/tv2/sisyfos-audio-controller/commit/d9be8916faa2118153d8cf88f08de0f94d38a3b2)) + + +### Performance Improvements + +* Decreased build size. ([ebf9218](https://github.com/tv2/sisyfos-audio-controller/commit/ebf921847568865cfa22d846f74cabf0e1b02684)) + + +### Continuous Integration + +* Removed unnecessary steps. ([4270cde](https://github.com/tv2/sisyfos-audio-controller/commit/4270cdef1967eda262d927b82f7cd18d5e210a05)) + + +### Code Refactoring + +* Cleanup + prettier moved to root package. ([9d66b5e](https://github.com/tv2/sisyfos-audio-controller/commit/9d66b5ee4f072e548c3d047cb522ebb9ac5b5a9e)) +* Moved release folder to desktop/dist. ([48d012f](https://github.com/tv2/sisyfos-audio-controller/commit/48d012ff6b7ba53c52202930dfb19c7b8112e4ee)) +* Moved shared constants into 'constants' folder. ([2b807a8](https://github.com/tv2/sisyfos-audio-controller/commit/2b807a8cf50133ffb8ee3dfd80b2390e6c32edbc)) +* Updated dockerfile + dockerignore to respect new project structure. ([755c8c0](https://github.com/tv2/sisyfos-audio-controller/commit/755c8c04e39ebd3e4334a89cefe0350709e86f8e)) +* Using process.cwd to find storage folder. ([195eb03](https://github.com/tv2/sisyfos-audio-controller/commit/195eb0334a2892359185597a089ba2187ddfb404)) + + +## [4.17.0](https://github.com/tv2/sisyfos-audio-controller/compare/v4.16.0...v4.17.0) (2022-02-23) + +### Features + +- better restart handling after updating settings ([0db1dab](https://github.com/tv2/sisyfos-audio-controller/commit/0db1dab9aaa178460dd8025e913f560377efbd18)) +- Hide load routing - when Sisyfos is not in settings=1 mode ([21e7e24](https://github.com/tv2/sisyfos-audio-controller/commit/21e7e2436441be447542727002bc6ee86bfa034b)) + +### Bug Fixes + +- automation labels fallback ([f854be0](https://github.com/tv2/sisyfos-audio-controller/commit/f854be0431a7f488d0b9372620d1702d674dffcb)) +- default label setting if undefined ([eab45ac](https://github.com/tv2/sisyfos-audio-controller/commit/eab45ac6c2ae904b4969d4a271a87a1be6e2ff06)) +- Midas - mixerTimeout should not start before metering data are recieved ([59b1857](https://github.com/tv2/sisyfos-audio-controller/commit/59b1857ccb215d982a88700fc07ad4d27fe85f37)) +- update mock data to match VuMeter ([2e56010](https://github.com/tv2/sisyfos-audio-controller/commit/2e560100d337541b2059178c6248497857d151db)) +- when adding a new channel to monitor send, other channels could have the same send active (because of expanded array having null values) ([fe6a34b](https://github.com/tv2/sisyfos-audio-controller/commit/fe6a34b96461708eea72d243f8ca62d448b58966)) +- When chaning number of faders, all monitor settings and routing was lost. ([d40a44c](https://github.com/tv2/sisyfos-audio-controller/commit/d40a44c8793bec50a3bc0bafc8ff7fada4954f03)) +- When setting Auxlevel on an index higher than the length of the array, unused items would be set as undefined instead of -1 ([0fbbcfc](https://github.com/tv2/sisyfos-audio-controller/commit/0fbbcfc5287688240e27295fd733da8d4caed6c9)) + +## [4.16.0](https://github.com/tv2/sisyfos-audio-controller/compare/v4.15.2...v4.16.0) (2021-12-14) + +### Features + +- Electron build for Mac and Windows ([cb52d03](https://github.com/tv2/sisyfos-audio-controller/commit/cb52d033b5274c2be88c0632a98fda86dd98bfe2)) + +### Bug Fixes + +- add electron.js file ([f839292](https://github.com/tv2/sisyfos-audio-controller/commit/f8392929e0c102574f123286fcd3537f8fd85a17)) +- Docker image size - add ./public/ to .dockerignore ([57e6f64](https://github.com/tv2/sisyfos-audio-controller/commit/57e6f644772c519885732740f02d57e26b2dd2fe)) +- Dockerfile - build node_modules as production ([41b39e9](https://github.com/tv2/sisyfos-audio-controller/commit/41b39e94b6f2503acdede75266c7b72ca6ed84f0)) +- Dockerfile - cache clean added ([11860af](https://github.com/tv2/sisyfos-audio-controller/commit/11860af9c77d943a14d04ee3aed43b022a815f4f)) +- package.json was not following .editorconfig 4 space indent_size ([72c2fea](https://github.com/tv2/sisyfos-audio-controller/commit/72c2fea19c95df4e1e90f18b3c862dad18ce1439)) +- remove electron and electron builder from Dockerimage ([cf33b6e](https://github.com/tv2/sisyfos-audio-controller/commit/cf33b6e70806057d03dba10825c6ff697d6b35be)) +- remove typescript and prettier from dockerbuild ([7d21d39](https://github.com/tv2/sisyfos-audio-controller/commit/7d21d399ee59d6c344ce0715b352ed29f749316e)) +- type - added double yarn in last commit ([d2bdff8](https://github.com/tv2/sisyfos-audio-controller/commit/d2bdff81e422b13f8f63e6712dd9af0b465a6208)) +- when start Sisyfos for the first time, it will crash if you touch faders ([102e58a](https://github.com/tv2/sisyfos-audio-controller/commit/102e58a2e45c96da5d4888bb94f4cf8e8dc491e4)) + +### [4.15.2](https://github.com/tv2/sisyfos-audio-controller/compare/v4.15.1...v4.15.2) (2021-12-13) + +### Bug Fixes + +- Change node version in Docker build to match github action tests ([012027f](https://github.com/tv2/sisyfos-audio-controller/commit/012027fca0b3caf9ec7c8827f7f2fc080606eea0)) + +### [4.15.1](https://github.com/tv2/sisyfos-audio-controller/compare/v4.15.0...v4.15.1) (2021-12-13) + +### Bug Fixes + +- Added dummy procces.env to client side. ([322e573](https://github.com/tv2/sisyfos-audio-controller/commit/322e5732408a61019847f5bc2adc7fcc0d3dd7ce)) + +## [4.15.0](https://github.com/tv2/sisyfos-audio-controller/compare/v4.14.0...v4.15.0) (2021-12-10) + +### Features + +- Changed logger from winston to tv2 mediatech logger. ([ab20456](https://github.com/tv2/sisyfos-audio-controller/commit/ab204564e1b0e276332715195b7421dd21ff74c1)) +- Full Ch Strip overall is scaling correct now ([1401a55](https://github.com/tv2/sisyfos-audio-controller/commit/1401a551011da5bdaf2a20e0c9be1e75fcf02b30)) +- Full channelstrip GUI scaling - initial changes ([4d49bcc](https://github.com/tv2/sisyfos-audio-controller/commit/4d49bcc0345808dcf6c2d409f1b2dfeccb34a2fb)) +- fullch strip GUI - split Eq part to own component. ([eb6fa42](https://github.com/tv2/sisyfos-audio-controller/commit/eb6fa4259d50672bf40377da2f6fb4bbf150b940)) +- Graphical Eq scaleable - prepared Reduction meter ([8ade6da](https://github.com/tv2/sisyfos-audio-controller/commit/8ade6da02ddae688a2b9d748b9ffc8a1dcd156a7)) + +### Bug Fixes + +- Bumped github actions workflows. ([e98080b](https://github.com/tv2/sisyfos-audio-controller/commit/e98080bb0dbb0af0478719a57c602e67c8c639d3)) +- don't scale reduction meters for now ([901df87](https://github.com/tv2/sisyfos-audio-controller/commit/901df875b0e2dc442bd515018314621c5e127dba)) +- Fixated logger version to 1.0.4, since newer uses fs. ([652e4ae](https://github.com/tv2/sisyfos-audio-controller/commit/652e4ae82455a9261568514a61f4f409d0281d62)) +- reduction meter align -6dB ([87d9f33](https://github.com/tv2/sisyfos-audio-controller/commit/87d9f3303ffb34d77789505dc4c2513ef3966350)) +- Updated yarn.lock. ([9fd96a9](https://github.com/tv2/sisyfos-audio-controller/commit/9fd96a9b5e77525a00dde174e93110fffb8abb0e)) + +## [4.14.0](https://github.com/tv2/sisyfos-audio-controller/compare/v4.13.2...v4.14.0) (2021-11-26) + +### Features + +- Added fader-toggling to mic tally view ([803ffda](https://github.com/tv2/sisyfos-audio-controller/commit/803ffdaf31731a878aee8d97c6027243c0c09737)) +- Comp On/Off - CSS styling ([f981d77](https://github.com/tv2/sisyfos-audio-controller/commit/f981d7746e139277ef135c15156b162b36d3fbe6)) +- Double click on Fader in the 0dB area will set the Fader to 0dB ([e29c939](https://github.com/tv2/sisyfos-audio-controller/commit/e29c939d924430a5d270d2778399c8e0023b6c39)) +- Midas - Comp On/Off functionality implemented - ToDo GUI - CSS ([d3f816a](https://github.com/tv2/sisyfos-audio-controller/commit/d3f816a32275676d99a97b845435a1a9a869a56f)) +- Midas - GUI Ratio on compressor is now from a list of values ([cb48a27](https://github.com/tv2/sisyfos-audio-controller/commit/cb48a274519409efc640f085a9a57f955b0fa369)) +- Midas reduction meter, add 6db and 12db reduction on scale ([7f79ff6](https://github.com/tv2/sisyfos-audio-controller/commit/7f79ff611172b2647740fd1fc8c8a97da57f7764)) +- valuesAsLabels - show min and max in GUI ([a5489f8](https://github.com/tv2/sisyfos-audio-controller/commit/a5489f8b7c2de4bbca42c248ec4a9419840fb3b2)) +- When using Sisyfos in manual mode (automation mode off) a SlowFade toogle option is added to faders ([67855fd](https://github.com/tv2/sisyfos-audio-controller/commit/67855fd02e14c7c78c0107c3730e428fdf4bc3e8)) + +### Bug Fixes + +- Added 'SLOW FADE' to translation list (i18n.ts) ([dbb3160](https://github.com/tv2/sisyfos-audio-controller/commit/dbb3160580230778ed3c3ed7a73f287fbe1f5141)) +- Added modal for confirming toggling for mic-tally ([27183f2](https://github.com/tv2/sisyfos-audio-controller/commit/27183f22e5a32eca08c15523a2b755690d939496)) +- Midas - when loading a new preset, settings was not received ([a4505b7](https://github.com/tv2/sisyfos-audio-controller/commit/a4505b7b48076f4eca956f0bf6e4769b825cb53f)) +- Midas metering convert dB to Lin ([cc26cc7](https://github.com/tv2/sisyfos-audio-controller/commit/cc26cc725a6f4b6066b787f7a39e895d5c2fbb11)) +- Midas Reduction meter should not be converted to log ([63e05b7](https://github.com/tv2/sisyfos-audio-controller/commit/63e05b7d16df2094030f3cb0a1869b5708adc65b)) +- Removed ?minimonitor=1 from code and README. ([d74b69b](https://github.com/tv2/sisyfos-audio-controller/commit/d74b69b73452ca74b97b8f72e35522ad774cce78)) +- use minLabel AND maxLabel when calculating received OSC message ([c93a0b0](https://github.com/tv2/sisyfos-audio-controller/commit/c93a0b0fcd0f353a2a90f0bfd5e9c30d6e802c4e)) +- Use version from bump-version instead of package.json in node-ci.prod ([ef8c1d7](https://github.com/tv2/sisyfos-audio-controller/commit/ef8c1d747076b4e57df319256774c68a754fe5b4)) + +### Styles + +- Added small indications for muted mic tally ([c9a266f](https://github.com/tv2/sisyfos-audio-controller/commit/c9a266f1a1a619d748be58389cf44c3fe4478320)) +- Updated mic tally appearance and responsiveness ([6c6f65d](https://github.com/tv2/sisyfos-audio-controller/commit/6c6f65ddd840395948b78d788d19237921d697b1)) + +### [4.13.2](https://github.com/tv2/sisyfos-audio-controller/compare/v4.13.1...v4.13.2) (2021-11-09) + +### Bug Fixes + +- Updated github actions workflow for dockerhub tag generation ([47e6ea9](https://github.com/tv2/sisyfos-audio-controller/commit/47e6ea9da8ad7385c600dc948ac18408569faa92)) + +### [4.13.1](https://github.com/tv2/sisyfos-audio-controller/compare/v4.13.0...v4.13.1) (2021-11-09) + +### Bug Fixes + +- Dockerfile installs all dependencies ([115e9d6](https://github.com/tv2/sisyfos-audio-controller/commit/115e9d629c72dc205347b9830b66cb8b7d90e142)) + +### Code Refactoring + +- Removed standard-version ([b933276](https://github.com/tv2/sisyfos-audio-controller/commit/b933276bc676cda0e98e717c81a8168f766c03af)) + +## [4.13.0](https://github.com/tv2/sisyfos-audio-controller/compare/v4.12.0...v4.13.0) (2021-11-09) + +### Features + +- Added dev github actions workflow ([1c1454b](https://github.com/tv2/sisyfos-audio-controller/commit/1c1454b13ad68c49de6f4c7108b85c147e212575)) +- Mic tally view added + better routing ([f607b7e](https://github.com/tv2/sisyfos-audio-controller/commit/f607b7e2c583d2500fee63b2ce4556ac08a4fcb6)) +- Updated github actions workflow. ([765d9ad](https://github.com/tv2/sisyfos-audio-controller/commit/765d9ad964426ab6114d753a9275e0378401edb2)) + +### Bug Fixes + +- Only install production dependencies when building Dockerfile ([8ab2e7d](https://github.com/tv2/sisyfos-audio-controller/commit/8ab2e7dfe476ca373c6845fbeb609cc9aa125092)) +- raising buffer interval for Midas to 2ms, as this stabilize the crash happening on full load from 24hours to at least 7 days. ([1d0e4a8](https://github.com/tv2/sisyfos-audio-controller/commit/1d0e4a81158ca6f8c8b169979405afbaacfec68a)) + +## [4.12.0](https://github.com/tv2/sisyfos-audio-controller/compare/v4.11.3...v4.12.0) (2021-10-26) + +### Features + +- added mixer timeout in mixer protocol interface. ([c9c49ca](https://github.com/tv2/sisyfos-audio-controller/commit/c9c49ca4f9757af99425c845cc632fc2e5121cbd)) +- Added mixertimeout support for Midas mixers. For a fast warning if mixer is not responding. ([b25efd5](https://github.com/tv2/sisyfos-audio-controller/commit/b25efd5d70392761999ed7dba093d6494ed87508)) +- Input Gain on Small channel strip ([a1e0be1](https://github.com/tv2/sisyfos-audio-controller/commit/a1e0be1c8f8cd4b3a2b833664f53eabcc3227669)) +- Update Winston logger and README.md after Elastic plugin was updated ([c9b3367](https://github.com/tv2/sisyfos-audio-controller/commit/c9b33672e98d8807131728ec13c4432e6490b9ba)) + +### [4.11.3](https://github.com/tv2/sisyfos-audio-controller/compare/v4.11.2...v4.11.3) (2021-09-17) + +### Bug Fixes + +- emit labels over automation protocol ([46eff39](https://github.com/tv2/sisyfos-audio-controller/commit/46eff39965514505af9287017978ec1c7efa8500)) + +### [4.11.2](https://github.com/tv2/sisyfos-audio-controller/compare/v4.11.1...v4.11.2) (2021-09-03) + +### Bug Fixes + +- docker image workflow ([d4f733c](https://github.com/tv2/sisyfos-audio-controller/commit/d4f733ce70347e5c0bc2d1199edc703031a9bb4b)) + +### [4.11.1](https://github.com/tv2/sisyfos-audio-controller/compare/v4.11.0...v4.11.1) (2021-08-30) + +### Bug Fixes + +- Automation protocol should not crossfade on channels with ignoreAutomation active ([3fbe07e](https://github.com/tv2/sisyfos-audio-controller/commit/3fbe07ef9216c297e82eaa811e5d564d02cdb0d9)) + +## [4.11.0](https://github.com/tv2/sisyfos-audio-controller/compare/v4.10.0...v4.11.0) (2021-08-19) + +### Features + +- vMix - basic receive data and connetiont established ([a2d99da](https://github.com/tv2/sisyfos-audio-controller/commit/a2d99da3f22948060c0ae5c00bdfc5a6912a94e0)) +- VMix - Faders, Mute, PFL, Gain & Matrix Select ([6551e22](https://github.com/tv2/sisyfos-audio-controller/commit/6551e2221e69aa3d88911d740bda340d6648ac53)) +- vmix - initial vmix setup (copy form osc) ([7784eb2](https://github.com/tv2/sisyfos-audio-controller/commit/7784eb25e19a78d4697c434d966db7eeb7b61e98)) +- vMix - initial working on 2 way connection ([bfbce5b](https://github.com/tv2/sisyfos-audio-controller/commit/bfbce5b9635a4dd50f06f6d9867a17cab45b00d8)) +- vmix add vmix protocol files ([e7354f1](https://github.com/tv2/sisyfos-audio-controller/commit/e7354f1507340805fcc4c4ba45526b7dcee13257)) + +### Bug Fixes + +- yarn had been added to dependencies ([db82974](https://github.com/tv2/sisyfos-audio-controller/commit/db8297451f7d036c379057c6ffe5ffaba8fb16a0)) + +## [4.10.0](https://github.com/tv2/sisyfos-audio-controller/compare/v4.9.1...v4.10.0) (2021-08-18) + +### Features + +- label system with user, automation & channel labels ([81e9d5b](https://github.com/tv2/sisyfos-audio-controller/commit/81e9d5b6a83fa6c4ef63c128facad72c30c23ecc)) +- use labels in automation protocol ([04d454c](https://github.com/tv2/sisyfos-audio-controller/commit/04d454ce3893d46140aa37d977bb6876afc79fea)) + +### Bug Fixes + +- wrong test command ([0e4d69a](https://github.com/tv2/sisyfos-audio-controller/commit/0e4d69a2f0074780359162647c9c9f621c82dc73)) + +### [4.9.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.9.0...v4.9.1) (2021-07-26) + +### Bug Fixes + +- Fade down was sending command in each loop in setInterval not respecting drivers dispatchResolution ([283cad0](https://github.com/olzzon/sisyfos-audio-controller/commit/283cad02850753ba13c6901725518ebbebaf2218)) +- If default.shot file is missing Sisyfos couln´t startup because trying to set assigned fader on store before faders in store was recreated. ([ece0623](https://github.com/olzzon/sisyfos-audio-controller/commit/ece06235849470b3e099facc153fcece9d16378e)) +- OSC buffer added to avoid overloading of Midas mixers ([0e4607b](https://github.com/olzzon/sisyfos-audio-controller/commit/0e4607ba9b033d5a6643709cf489262ff772d331)) +- OSC connection buffer interval lowered to 0.5ms ([9302cf3](https://github.com/olzzon/sisyfos-audio-controller/commit/9302cf38f523194be5e987b4319d931cbd993341)) + +## [4.9.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.8.3...v4.9.0) (2021-06-22) + +### Features + +- remove logging til logfile.log - as this is not used ([59d6b03](https://github.com/olzzon/sisyfos-audio-controller/commit/59d6b031a5e76175d9c775ebb6a3a3a0ef409eca)) + +### [4.8.3](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.8.2...v4.8.3) (2021-06-22) + +### Bug Fixes + +- remove winston-elasticsearch support. Caused crash and is no longer used. ([955d52a](https://github.com/olzzon/sisyfos-audio-controller/commit/955d52a4c66304f6e717d249e54110f0edd58852)) + +### [4.8.2](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.8.1...v4.8.2) (2021-05-19) + +### Bug Fixes + +- resolution on hosted-git-info package to force fix vulnerability ([ef0c283](https://github.com/olzzon/sisyfos-audio-controller/commit/ef0c28333b6329c1ed10c5b46ea73c54c45e3cff)) + +### [4.8.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.8.0...v4.8.1) (2021-05-17) + +### Bug Fixes + +- load of snapshot was not enabled. Will now load full snapshot. ToDo filter output non-config based values. ([18fbc22](https://github.com/olzzon/sisyfos-audio-controller/commit/18fbc22e1a8827fa932719f40be431a71b4306dc)) + +## [4.8.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.7.1...v4.8.0) (2021-03-25) + +### Features + +- Display Sisyfos version in Settings menu ([d5ec220](https://github.com/olzzon/sisyfos-audio-controller/commit/d5ec220ace35557d437482ea49d6dea41ea00ff3)) + +### Bug Fixes + +- migration test also for minor version changes ([1ad86d6](https://github.com/olzzon/sisyfos-audio-controller/commit/1ad86d6075d170eba43e9bbe96ae9cac4cd3effd)) + +### [4.7.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.7.0...v4.7.1) (2021-03-25) + +### Bug Fixes + +- migrations version handling as numeric values ([95b80d5](https://github.com/olzzon/sisyfos-audio-controller/commit/95b80d53c60ebff9cd13696d6e8ded7afadf1bda)) + +## [4.7.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.6.0...v4.7.0) (2021-03-25) + +### Features + +- add fader store set and remove assigned channel from fader ([73749ab](https://github.com/olzzon/sisyfos-audio-controller/commit/73749ab5245f47be0b5f64738e6426a3e4cf0af5)) +- CSS - less space for Multiple meter ([dc1c4e4](https://github.com/olzzon/sisyfos-audio-controller/commit/dc1c4e4a0bd558ce10a4dc0ef81c6ece86220ec1)) +- implemented Midas support for multiple meters based on the assigned channels to a fader. ToDo full support for multiple mixers ([01a6e36](https://github.com/olzzon/sisyfos-audio-controller/commit/01a6e363cd7f5080cad310ae43032b266b0c4b5b)) +- inital migration.ts and version check. ([15e9b79](https://github.com/olzzon/sisyfos-audio-controller/commit/15e9b797a63c032f27af28a732cfb6d1da97df72)) +- Migration - handler updates from 4.xx to 4.6 and also .shot files from 3.xx ([60da92c](https://github.com/olzzon/sisyfos-audio-controller/commit/60da92c10bae6b49a250af2abe13925d5e387526)) +- prepare change to meter pr assigned channel ([fefa810](https://github.com/olzzon/sisyfos-audio-controller/commit/fefa810ed33f972dfd7564224db7e0007dac57fd)) + +### Bug Fixes + +- import of faderActions.ts had bad path reference ([39c9f05](https://github.com/olzzon/sisyfos-audio-controller/commit/39c9f05e91da5b246ff9bafc8f19deb6b76a777a)) +- migration should write settings in sync mode to prevent async loading of old settings ([00e004f](https://github.com/olzzon/sisyfos-audio-controller/commit/00e004ffccde364301685a59c743282e0db382db)) +- OSC mixerconnection - make initializeCommands optional for protocols without it ([d008250](https://github.com/olzzon/sisyfos-audio-controller/commit/d00825031e2993cde8ec400bade3637c7a688db4)) + +## [4.6.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.5.2...v4.6.0) (2021-03-19) + +### Features + +- code cleanup, remove unused emptyMixerProtocol() function in OSC mixer protocols ([66e3d9c](https://github.com/olzzon/sisyfos-audio-controller/commit/66e3d9cbdca19911f227f567293020ac103d0cbf)) +- refactor - all snaps code from old implementation removed ([62d2ea2](https://github.com/olzzon/sisyfos-audio-controller/commit/62d2ea2a0761bdc3a0cd827e42b87b6600dfb125)) +- refactor - rename channel to faderIndex in all faderReducers and faderActions ([e738ba4](https://github.com/olzzon/sisyfos-audio-controller/commit/e738ba46777706599f14804653e92d7c5afb600c)) +- refactor - rename chConnection to chMixerConnection ([fc22e4e](https://github.com/olzzon/sisyfos-audio-controller/commit/fc22e4e5adb7c95a124bc88bbee0fbfc43d181da)) +- settings are changed so they are only available when /?settings=1 is added ([48f61a4](https://github.com/olzzon/sisyfos-audio-controller/commit/48f61a4a45f4fc8d1751b59e41ea477d717d040c)) + +### Bug Fixes + +- delay button had a + sign in from nomatter if it was positive og negative ([3aa404a](https://github.com/olzzon/sisyfos-audio-controller/commit/3aa404adf0928e79854c7d2061c832e4a8a76214)) +- OscMixerConnection check parameter as optional for support when not in the mixerprotocol ([609cb91](https://github.com/olzzon/sisyfos-audio-controller/commit/609cb9157a27ee8441bfe3c5df81ee7968d693b9)) +- types for ClassNames and .babelrc for jest tests ([f9e4d16](https://github.com/olzzon/sisyfos-audio-controller/commit/f9e4d1638bbabab8d8c7aa811c9783f4c7648bad)) +- update tests for support of faderActions ([731ce0f](https://github.com/olzzon/sisyfos-audio-controller/commit/731ce0f0c787e6b8db5eaa42e5daf57d3a54d59e)) + +### [4.5.2](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.5.1...v4.5.2) (2021-03-18) + +### Bug Fixes + +- Fader resolution increased to 1/1000 so delay on Midas could be handled ([c8272dc](https://github.com/olzzon/sisyfos-audio-controller/commit/c8272dcf14aa7ff642a9561c8e3470f7e659113b)) + +### [4.5.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.5.0...v4.5.1) (2021-02-25) + +### Bug Fixes + +- Full channelstrip - vertical faders in react-slider module, inherited "reverse" setting from horisontal faders. ([30505ac](https://github.com/olzzon/sisyfos-audio-controller/commit/30505ac4c5cbf023e28143e5124e4cb52f0d6bbf)) + +## [4.5.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.4.0...v4.5.0) (2021-02-24) + +### Features + +- Midas/X32 - Input gain trim in full channel view ([6e3ccbc](https://github.com/olzzon/sisyfos-audio-controller/commit/6e3ccbc983390092a7977949adc2026e8dd50833)) +- More Generic Preset load files for midas/X32 ([bc292d4](https://github.com/olzzon/sisyfos-audio-controller/commit/bc292d436b5036e1265b1f8ed0355b2f8aac57f7)) +- show dB range on the fader ([d38b4ba](https://github.com/olzzon/sisyfos-audio-controller/commit/d38b4ba98e48cf7ddb8d95a484290f94b816fd96)) +- **ember:** load mixer snapshots ([14c4d71](https://github.com/olzzon/sisyfos-audio-controller/commit/14c4d715be1144be77a3c8c76823bb096e4baedf)) + +### Bug Fixes + +- casparcg online status ([b0c079d](https://github.com/olzzon/sisyfos-audio-controller/commit/b0c079d7558782d842062574b6ae5508b05e2867)) +- change PFL color to green ([40d8514](https://github.com/olzzon/sisyfos-audio-controller/commit/40d851463462612ad76038ec17ae88a295dc5a26)) +- default number of custompages changed from 16 to 4 ([353ac95](https://github.com/olzzon/sisyfos-audio-controller/commit/353ac95b86c280ea0862abe68ddcf05783e3c398)) +- hide unused Lawo Ruby channels ([c7356cb](https://github.com/olzzon/sisyfos-audio-controller/commit/c7356cb618ecfa4ed5a25958bb6db55eb42b3c0c)) +- mc2 input gain ([7a07fdc](https://github.com/olzzon/sisyfos-audio-controller/commit/7a07fdc6b805a693325566476fa060ddb4990016)) +- mc2 mixer protocol ([0602048](https://github.com/olzzon/sisyfos-audio-controller/commit/0602048b0b4237f288f82942bf0f0f62d736d78f)) +- Midas/Behringer X32 load first scene in mixer (index 0) ([ee31992](https://github.com/olzzon/sisyfos-audio-controller/commit/ee3199204a4d5dc5b6d5ed1caafa190001962214)) +- Midas/X32 - Q-param in Eq was reverted and non exponential ([41e3809](https://github.com/olzzon/sisyfos-audio-controller/commit/41e380985a0febd00e733b3647659b6684aa2299)) +- mixer status + mc2 reconnects ([80bc452](https://github.com/olzzon/sisyfos-audio-controller/commit/80bc45293f98f6c12171376e2aa06117cf8ee4fb)) +- OSC protocol - set mixer online when auto reconnecting ([18ac6c0](https://github.com/olzzon/sisyfos-audio-controller/commit/18ac6c034fad2af9bfb067dabc4b9331834beb9a)) +- rename "Gain Trim" to "Input" as gain trim is the name of the parameter ([804235b](https://github.com/olzzon/sisyfos-audio-controller/commit/804235bc41a55dce5716ae89725fc4c7d148bdb4)) +- show storage with settings disabled ([a7563a6](https://github.com/olzzon/sisyfos-audio-controller/commit/a7563a6583ecb1db2bbb648a1a831c075f14d8b0)) +- ui crash when an invalid channel number was used by automation ([66ee580](https://github.com/olzzon/sisyfos-audio-controller/commit/66ee5803a6cb8f750120fed42694417984a6d46b)) + +## [4.4.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.3.0...v4.4.0) (2020-11-14) + +### Features + +- multi-channel vu meter ([5447042](https://github.com/olzzon/sisyfos-audio-controller/commit/54470423e27fba3ea1d70b59505b2aeda2907039)) + +### Bug Fixes + +- directly setting fader should not send any more commands ([f196cc1](https://github.com/olzzon/sisyfos-audio-controller/commit/f196cc19caddd585b7e259910f2f012c8c399099)) +- Midas/Behringer X32 Gain reduction metering, implemented in new metering structure ([de5c255](https://github.com/olzzon/sisyfos-audio-controller/commit/de5c255ba5a670aa60d57a13ce616f94655ec2dd)) +- Multiple Mixers intial state, if default.shot was empty, a crash could occour. ([ca94894](https://github.com/olzzon/sisyfos-audio-controller/commit/ca94894ee71d9afbb93afb91c09b965bff251a0f)) +- Multiple we clients - returning -1 when using indexOf() cause all clients reference to be deleted ([006b7ec](https://github.com/olzzon/sisyfos-audio-controller/commit/006b7ecdfc4b7cb342147afad5b6e5aff4ad5b0a)) +- put vu messages back on main socket ([d23d3ca](https://github.com/olzzon/sisyfos-audio-controller/commit/d23d3caf69a700a8341e60f974a351b107137a2b)) +- Reduction metering - only update active channelstrip ([948ab79](https://github.com/olzzon/sisyfos-audio-controller/commit/948ab798b9e8ed17de1f298f8e874c1219c0a68e)) +- remove ccg component from new ChannelStripFull ([a11de4f](https://github.com/olzzon/sisyfos-audio-controller/commit/a11de4f743651ab1002f3897f7096cba95fe113c)) +- subscribe to VU meters upon connection ([bf5fce7](https://github.com/olzzon/sisyfos-audio-controller/commit/bf5fce76d95c61a2578786f28d2288baadd115b7)) +- use getState on client side instead of servers redux store ([18d0562](https://github.com/olzzon/sisyfos-audio-controller/commit/18d0562a04ed812ed8844321842cb84706d85a14)) +- Use sendVuLevel for reduction in Behringer XR and plain OSC protocol ([6300181](https://github.com/olzzon/sisyfos-audio-controller/commit/6300181a0d886de5dee4881ce1fa0aa0afb00a36)) +- **casparcg:** better fader response ([50b3c30](https://github.com/olzzon/sisyfos-audio-controller/commit/50b3c30191409272f0db7ef0b2cba9a868d0d4e6)) +- **casparcg:** better support for multiple mixers ([9caa210](https://github.com/olzzon/sisyfos-audio-controller/commit/9caa210f4ad9201447aa1c230a965599c7045e35)) +- **casparcg:** calculate proper VU level ([ee89d7c](https://github.com/olzzon/sisyfos-audio-controller/commit/ee89d7c45e283826609493e64dfad0b101abdaca)) +- **casparcg:** use normal input selector rather than custom component ([f33a18f](https://github.com/olzzon/sisyfos-audio-controller/commit/f33a18fb5b212b1a5fb56820983fc41adcc76e4a)) + +## [4.3.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.2.0...v4.3.0) (2020-11-09) + +### Features + +- full ch strip - digit on gain read out, adjusted freq indicators ([26e44b5](https://github.com/olzzon/sisyfos-audio-controller/commit/26e44b58959c5cc22c718d71042c5ce98a550742)) +- full ch strip - initial setup ([48c08de](https://github.com/olzzon/sisyfos-audio-controller/commit/48c08defc39962e8728c9a1054bc5ab11ad5bc18)) +- full ch strip - list all eq feature (preparation for graphic Eq GUI) ([0f68a0d](https://github.com/olzzon/sisyfos-audio-controller/commit/0f68a0da6297dcd677c6f1af983df7ea9a3f24ee)) +- full ch strip - OSCMixerProtocol a lot of code removed with support for fxParams ([486dfce](https://github.com/olzzon/sisyfos-audio-controller/commit/486dfce0a91168e5f50b7867973cb0e89febab82)) +- full ch strip - set draggrid to 20x20 for better performance. ([b243a71](https://github.com/olzzon/sisyfos-audio-controller/commit/b243a713a3cfb6b9c380717505505549729afaad)) +- full ch strip graphic eq - better colors ([abf4e10](https://github.com/olzzon/sisyfos-audio-controller/commit/abf4e1069c309e54a2a59caa3f6cd9d426527059)) +- full ch-strip - full comp parameters on X32 mixer ([4defbad](https://github.com/olzzon/sisyfos-audio-controller/commit/4defbad86dee5538aee0734cc0e999719ae396bb)) +- full ch-strip - gain freq values in Eq ([5e4ae42](https://github.com/olzzon/sisyfos-audio-controller/commit/5e4ae42ed2a5a146eb35d2f3f1e88583d3f1f04b)) +- full ch-strip - graphical eq drag gain+freq working ([d4efe28](https://github.com/olzzon/sisyfos-audio-controller/commit/d4efe2862d3cd2c6386c194303f3b9bce9adc8da)) +- full ch-strip - logarithmic Freq on graph eq, adding Q ([f4e63b0](https://github.com/olzzon/sisyfos-audio-controller/commit/f4e63b0f771c1e33fb2c1d85ccdc3b4e5405fc85)) +- full ch-strip - XY, freq labels zero gain etc ([5382c6f](https://github.com/olzzon/sisyfos-audio-controller/commit/5382c6f4f568c623b5b2fbb527e65b5a533a11fa)) +- full ch-strip add new files ([df1f538](https://github.com/olzzon/sisyfos-audio-controller/commit/df1f538803ced4b665a45ee4b73a7a0b27b9416a)) +- full ch-strip move eq to seperate function preparing EQ GUI ([b746112](https://github.com/olzzon/sisyfos-audio-controller/commit/b746112d30f347eece51f905dadb41a97f90f692)) +- Full channelstrip - only show eq,comp,delay if part of protocol ([104cbbc](https://github.com/olzzon/sisyfos-audio-controller/commit/104cbbce3c1f76644d06ec9cdea856a85daca0fb)) +- full chstrip - clean up code - delay buttons moved to array ([12937e4](https://github.com/olzzon/sisyfos-audio-controller/commit/12937e44c20b20c31034bc2ad06c0efa3b4483af)) +- full chstrip - Delay fader uses fxParam ([55d7de4](https://github.com/olzzon/sisyfos-audio-controller/commit/55d7de4b4bc3beb4862d46ae1d9cbf92d3ec0a3e)) +- full-ch-strip - move monitor sends to upper area of GUI ([6dea7fe](https://github.com/olzzon/sisyfos-audio-controller/commit/6dea7fefaa9735497665a4074fc41b12985f6236)) +- labels on parameters in chstrip ([592dc2c](https://github.com/olzzon/sisyfos-audio-controller/commit/592dc2c42bdf5913a4008e6adbcadf6286c9631b)) + +### Bug Fixes + +- checkFxCommands didn´t filter out non numbered ([d98f592](https://github.com/olzzon/sisyfos-audio-controller/commit/d98f59202516d3b801dc69eb6934df3e98a1e959)) +- Custom Pages "ALL" button didn´t work ([c2f500e](https://github.com/olzzon/sisyfos-audio-controller/commit/c2f500eb6bc8ab75719e39b59d0de3e0fb331fc0)) +- datastructure didn´t reference to key but to index. ([75c5944](https://github.com/olzzon/sisyfos-audio-controller/commit/75c5944f9071fbf04f4a11e87d4f717e1b8f27a9)) +- full ch strip - better placement of freq text on graph eq ([28a96ef](https://github.com/olzzon/sisyfos-audio-controller/commit/28a96efbbebe8efbcf9986da63d77cd9737ffd98)) +- full ch strip - crash when using mixer protocol without eq. ([2f9518c](https://github.com/olzzon/sisyfos-audio-controller/commit/2f9518c07bf7790a398de0dc6415aeddde7bb22c)) +- full ch strip - move log-lin conversion from graphic eq to freq readout ([de16b9b](https://github.com/olzzon/sisyfos-audio-controller/commit/de16b9b5e0e2c1c8cec7451ac8555fc1c78f755d)) +- full ch strip - typo: Q value always changed channel 0 ([c0f870d](https://github.com/olzzon/sisyfos-audio-controller/commit/c0f870def67f1828a7617adb356dabe8600936c5)) +- midas/behringer X32 initial fetch of all fx parameters ([d1a9cf0](https://github.com/olzzon/sisyfos-audio-controller/commit/d1a9cf001705bbc356991bc978cfee76717a1132)) +- min ratio in midas should be 1:1 ([c9abc07](https://github.com/olzzon/sisyfos-audio-controller/commit/c9abc0794700d7750a16971975a568558f1d25b0)) +- touchscreen event in graphical Eq ([54329f2](https://github.com/olzzon/sisyfos-audio-controller/commit/54329f293424cedc07c06ac10e14e4764227eeab)) +- Y axis in graphics Eq only draw minValue ([61300dc](https://github.com/olzzon/sisyfos-audio-controller/commit/61300dcff9eaae9ff0014a10ffa41c4ae66184cc)) + +## [4.2.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.1.0...v4.2.0) (2020-10-22) + +### Features + +- custom page menu - implementing page selector ([f755ece](https://github.com/olzzon/sisyfos-audio-controller/commit/f755ece52756677233cff200eb82122d49c28c9e)) +- custom pages menu - add css file to git - move "PAGES SETUP" in Channels view ([944c633](https://github.com/olzzon/sisyfos-audio-controller/commit/944c6335282c72772b5be0167a35641cf1180b4f)) +- custom pages menu - CCS for GUI ([b68599c](https://github.com/olzzon/sisyfos-audio-controller/commit/b68599c7ee4a7303b91390c1a18167db9f8cc5f6)) +- custom pages menu - css align tick boxes ([3bf4d60](https://github.com/olzzon/sisyfos-audio-controller/commit/3bf4d600afcd0fc0199fe866d4765ee29ae0eca1)) +- custom pages menu - initialize label field correctly ([5d7bf9a](https://github.com/olzzon/sisyfos-audio-controller/commit/5d7bf9a95d86aba05df94902aae85cab45357c3a)) +- custom pages menu - move from global space (window.customPages) to redux settings[0].customPages for realtime rendering ([865a467](https://github.com/olzzon/sisyfos-audio-controller/commit/865a467193c851c4fc1f3dafff3e6d3561f224b1)) +- custom pages menu - realtime update of fader config in GUI ([4f4c542](https://github.com/olzzon/sisyfos-audio-controller/commit/4f4c5426e6519c3d342ec37cbf5e1e082b838a05)) +- custom pages menu - set number of custom pages in Settings menu ([2167faa](https://github.com/olzzon/sisyfos-audio-controller/commit/2167faa92c15ec9f081577943fd4e17255e557ae)) +- custom pages menu - working - ToDo: CSS ([329014a](https://github.com/olzzon/sisyfos-audio-controller/commit/329014a3fa1da472a4628ee49232f02f392a9ee5)) +- custom pages setup - change label support ([93b8451](https://github.com/olzzon/sisyfos-audio-controller/commit/93b84518cab9ab761dc7090835a51c288774c82e)) +- custom pages setup menu - bind and undbind to first custom page working ([648f880](https://github.com/olzzon/sisyfos-audio-controller/commit/648f88074867b4e09088ef911f120096c60a1ace)) +- pages setup menu - creating menu and store ([70f7374](https://github.com/olzzon/sisyfos-audio-controller/commit/70f7374fd528b2728378a7c348a72f7cbeefc96d)) + +### Bug Fixes + +- OSC mixer protocol receiving channels not assigned to a fader should be ignored ([994e42d](https://github.com/olzzon/sisyfos-audio-controller/commit/994e42d5f5c1d93370687ed55ebc6dc43a1dd3ea)) +- OSC mixerprotocol initial mixer state was resetting preset fader state ([aecfcb2](https://github.com/olzzon/sisyfos-audio-controller/commit/aecfcb2c76844e4eb0633962aeb7a526af886208)) +- set all fader state, arguments was in wrong order. ([125bd1f](https://github.com/olzzon/sisyfos-audio-controller/commit/125bd1f9f7e2bbfb6b0d294705834cb1236d0bf9)) +- storeSetPage() didn´t handle the different type of page selectors correctly ([5425603](https://github.com/olzzon/sisyfos-audio-controller/commit/542560304895c76a1309613d77e6c9d40c016e6e)) + +## [4.1.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.0.2...v4.1.0) (2020-10-14) + +### Features + +- add button to toggle manual mode for all faders ([ee94d84](https://github.com/olzzon/sisyfos-audio-controller/commit/ee94d847b512c93a7b2bc3d0bedb8579a87ae5c0)) +- implemented Lawo MC2 support ([e78d2c4](https://github.com/olzzon/sisyfos-audio-controller/commit/e78d2c4cac2ec40de40824b930aaaec6e86b7f2e)) + +### Bug Fixes + +- **mc2:** remove firmware 5.6.0 support ([8568719](https://github.com/olzzon/sisyfos-audio-controller/commit/8568719c3d9708c732d6d5af8830327c6e79d8ac)) +- **mc2:** support mc2 firmware 5.6.0 ([fa80bde](https://github.com/olzzon/sisyfos-audio-controller/commit/fa80bde87eb0d61963a9234da74d2d712c200cf4)) +- dispatch manual fader movements immediately ([2552797](https://github.com/olzzon/sisyfos-audio-controller/commit/2552797dce35fc32b9a6f8e4b53e7c262c6b8198)) + +### [4.0.2](https://github.com/olzzon/sisyfos-audio-controller/compare/v4.0.1...v4.0.2) (2020-10-13) + +### Bug Fixes + +- limit speed of VU updates on mixers with independent VU and VU reduction protocol ([cb59a70](https://github.com/olzzon/sisyfos-audio-controller/commit/cb59a706d3b37c31d4aea6efa977e6ebcca9cb89)) +- Midas - Behringer X32 metering update correct when musing ultiple mixers with Vumeters ([0b628f0](https://github.com/olzzon/sisyfos-audio-controller/commit/0b628f09290e3787638b4fb4ee87779c1bbfdbf2)) +- remove console.log in midas.ts metering ([f7f4c24](https://github.com/olzzon/sisyfos-audio-controller/commit/f7f4c248f452f5ff0aa0a1333dc76cc810f7903b)) + +### [4.0.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v3.6.1...v4.0.1) (2020-10-12) + +### Features + +- adding support for multiple mixers in all product specific mixerConnections ([95209b5](https://github.com/olzzon/sisyfos-audio-controller/commit/95209b541d4d881d2358873571b3d7048063b0e0)) +- mixerconnection initialize multiple mixers ([b33ea95](https://github.com/olzzon/sisyfos-audio-controller/commit/b33ea950511e526ed7a97fb7baee918a58ad7331)) +- multiple faders - channel-fader routing ([6fdd8be](https://github.com/olzzon/sisyfos-audio-controller/commit/6fdd8beca00ad5465b71a1a4c96243e9a51a5445)) +- multiple mixers - Aux working for first mixer. ([37c0ab8](https://github.com/olzzon/sisyfos-audio-controller/commit/37c0ab8eb3fbff35f191ba4c83bd7e407343391d)) +- multiple mixers - behringer midas metering support ([0f6aff4](https://github.com/olzzon/sisyfos-audio-controller/commit/0f6aff403464d87f34b874757ecf6fb84aba6fc3)) +- multiple mixers - Channel Fader routing: clear all assignments ([d62f3ea](https://github.com/olzzon/sisyfos-audio-controller/commit/d62f3eaa2805394b64e61053f7388037bc79c5af)) +- multiple mixers - channel faders assign menu - label for each mixer ([f49a953](https://github.com/olzzon/sisyfos-audio-controller/commit/f49a953e1fbf1edab1538a353076a2162b47029f)) +- multiple mixers - clean up routing options ([32a4abb](https://github.com/olzzon/sisyfos-audio-controller/commit/32a4abba5c3766b73b84a169d61ef822513366a4)) +- multiple mixers - create channel structure and timing in front end ([c1871f0](https://github.com/olzzon/sisyfos-audio-controller/commit/c1871f0a19b40ed3a537c10c1251e91b320d5a85)) +- multiple mixers - move local Ip and port to "mixers" so multiple OSC protocols can be supported ([b071cca](https://github.com/olzzon/sisyfos-audio-controller/commit/b071cca4cd2c9579d2f57e2d49814e440aa73916)) +- multiple mixers - prepare channel-fader Routing ([5f55b95](https://github.com/olzzon/sisyfos-audio-controller/commit/5f55b95e44979673dc657bc379c537dafb186596)) +- multiple mixers - settings working ([a2657dc](https://github.com/olzzon/sisyfos-audio-controller/commit/a2657dcbe331f2031c279f8351d066a4eff9487e)) +- multiple mixers - update redux actions: outputLevel and fadeActive ([975f65b](https://github.com/olzzon/sisyfos-audio-controller/commit/975f65bf94638bc846102f2305109f78d7224f8e)) +- multiple mixers support loop through all mixers in generic connection ([f29b09f](https://github.com/olzzon/sisyfos-audio-controller/commit/f29b09ffd87ad46e3b07b5c2f07b2d48840658af)) +- multiple mixers, timer fade inout support ([f59036a](https://github.com/olzzon/sisyfos-audio-controller/commit/f59036af204f4d4a2441073d09dc46433248d458)) +- multiple-mixers implementing restore full channel store ([c2e524f](https://github.com/olzzon/sisyfos-audio-controller/commit/c2e524f1a4633f4179f13f7a1857117217523426)) +- preparing multiple mixer connections in channel store. ([c1ba41d](https://github.com/olzzon/sisyfos-audio-controller/commit/c1ba41d08ccacd6609bbae03d1011c812c18e2bf)) +- preparing support for multiple mixers in settings store ([1796992](https://github.com/olzzon/sisyfos-audio-controller/commit/1796992ac283a86daf3181cc8d4ac601ec478797)) +- settings.tsx preparing multiple audio mixers support ([d2076b2](https://github.com/olzzon/sisyfos-audio-controller/commit/d2076b2379b5d80670f0293d11aa2970a78e03de)) +- support multiple mixers in Fade in-out ([b67c06d](https://github.com/olzzon/sisyfos-audio-controller/commit/b67c06da7b1f91e01326183951de2d4748a8a3b8)) + +### Bug Fixes + +- crash when starting with a pre 4.xx settings.json file ([35b7732](https://github.com/olzzon/sisyfos-audio-controller/commit/35b7732980dcb5fbbdcc1049431d087855f3c14f)) +- deep clone to new mixer added in settings ([dc077be](https://github.com/olzzon/sisyfos-audio-controller/commit/dc077be58350870b622957672f1018993e292bee)) +- limit VU updatespeed to 100ms for performance issues on large mixer setups ([858acf1](https://github.com/olzzon/sisyfos-audio-controller/commit/858acf1e0f72f1c74581352d9648ca886d02374a)) +- metering - possibly undefined (wasn´t discovered, as the metering previously wasn´t visible if it was undefined) ([9ee5094](https://github.com/olzzon/sisyfos-audio-controller/commit/9ee5094b27440559812bd3fe755c83551e082f78)) +- mixer online forced rerendering. Mixer Online i still only status for first mixer. (ToDO: support all mixers in GUI) ([622cc2e](https://github.com/olzzon/sisyfos-audio-controller/commit/622cc2e16c4760896ef1a003c7c928a27a8e5e1e)) +- multiple mixers - assign channels to fader only assigned first mixer ([2086754](https://github.com/olzzon/sisyfos-audio-controller/commit/2086754bc1d60ce2460832b0e9af8118a9eae1e3)) +- multiple mixers - aux settings support for first mixer - ToDo: support multiple mixers ([921be2d](https://github.com/olzzon/sisyfos-audio-controller/commit/921be2d516255e7f51123ee115f451c7d93f5d8a)) +- multiple mixers - update mixer number of mixers - ch datastructure problem ([9b3642a](https://github.com/olzzon/sisyfos-audio-controller/commit/9b3642acbab86b04b46902e4f88c30d30c662864)) +- multiple mixers, mixerconnection reference to correct mixer instead of first one ([59dee5d](https://github.com/olzzon/sisyfos-audio-controller/commit/59dee5dbef36b7e2b64c78e3b63401e5db14e066)) +- multple mixers settings - port aux etc didn´t update correctly ([d87bc77](https://github.com/olzzon/sisyfos-audio-controller/commit/d87bc77dc123f417b1f4c6e66b3b8e499892c9bf)) +- OSC protocol - type in logger.info mixerport ([b95e3c8](https://github.com/olzzon/sisyfos-audio-controller/commit/b95e3c8fb3cfab18c6d00852877f4852d03a92d4)) +- re-render issue in miniChannels mixer ([a1fb85f](https://github.com/olzzon/sisyfos-audio-controller/commit/a1fb85f55298f38f9547ee8e20c1e3c22ce3ffdf)) +- typo - CHANNEL_ACTIONS constant was left over in SettingsStorage.ts ([91905a9](https://github.com/olzzon/sisyfos-audio-controller/commit/91905a97dcae750f20d2aa5464665a35b5888dd9)) + +## [4.0.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v3.6.1...v4.0.0) (2020-10-12) + +### Features + +- adding support for multiple mixers in all product specific mixerConnections ([95209b5](https://github.com/olzzon/sisyfos-audio-controller/commit/95209b541d4d881d2358873571b3d7048063b0e0)) +- mixerconnection initialize multiple mixers ([b33ea95](https://github.com/olzzon/sisyfos-audio-controller/commit/b33ea950511e526ed7a97fb7baee918a58ad7331)) +- multiple faders - channel-fader routing ([6fdd8be](https://github.com/olzzon/sisyfos-audio-controller/commit/6fdd8beca00ad5465b71a1a4c96243e9a51a5445)) +- multiple mixers - Aux working for first mixer. ([37c0ab8](https://github.com/olzzon/sisyfos-audio-controller/commit/37c0ab8eb3fbff35f191ba4c83bd7e407343391d)) +- multiple mixers - behringer midas metering support ([0f6aff4](https://github.com/olzzon/sisyfos-audio-controller/commit/0f6aff403464d87f34b874757ecf6fb84aba6fc3)) +- multiple mixers - Channel Fader routing: clear all assignments ([d62f3ea](https://github.com/olzzon/sisyfos-audio-controller/commit/d62f3eaa2805394b64e61053f7388037bc79c5af)) +- multiple mixers - channel faders assign menu - label for each mixer ([f49a953](https://github.com/olzzon/sisyfos-audio-controller/commit/f49a953e1fbf1edab1538a353076a2162b47029f)) +- multiple mixers - clean up routing options ([32a4abb](https://github.com/olzzon/sisyfos-audio-controller/commit/32a4abba5c3766b73b84a169d61ef822513366a4)) +- multiple mixers - create channel structure and timing in front end ([c1871f0](https://github.com/olzzon/sisyfos-audio-controller/commit/c1871f0a19b40ed3a537c10c1251e91b320d5a85)) +- multiple mixers - move local Ip and port to "mixers" so multiple OSC protocols can be supported ([b071cca](https://github.com/olzzon/sisyfos-audio-controller/commit/b071cca4cd2c9579d2f57e2d49814e440aa73916)) +- multiple mixers - prepare channel-fader Routing ([5f55b95](https://github.com/olzzon/sisyfos-audio-controller/commit/5f55b95e44979673dc657bc379c537dafb186596)) +- multiple mixers - settings working ([a2657dc](https://github.com/olzzon/sisyfos-audio-controller/commit/a2657dcbe331f2031c279f8351d066a4eff9487e)) +- multiple mixers - update redux actions: outputLevel and fadeActive ([975f65b](https://github.com/olzzon/sisyfos-audio-controller/commit/975f65bf94638bc846102f2305109f78d7224f8e)) +- multiple mixers support loop through all mixers in generic connection ([f29b09f](https://github.com/olzzon/sisyfos-audio-controller/commit/f29b09ffd87ad46e3b07b5c2f07b2d48840658af)) +- multiple mixers, timer fade inout support ([f59036a](https://github.com/olzzon/sisyfos-audio-controller/commit/f59036af204f4d4a2441073d09dc46433248d458)) +- multiple-mixers implementing restore full channel store ([c2e524f](https://github.com/olzzon/sisyfos-audio-controller/commit/c2e524f1a4633f4179f13f7a1857117217523426)) +- preparing multiple mixer connections in channel store. ([c1ba41d](https://github.com/olzzon/sisyfos-audio-controller/commit/c1ba41d08ccacd6609bbae03d1011c812c18e2bf)) +- preparing support for multiple mixers in settings store ([1796992](https://github.com/olzzon/sisyfos-audio-controller/commit/1796992ac283a86daf3181cc8d4ac601ec478797)) +- settings.tsx preparing multiple audio mixers support ([d2076b2](https://github.com/olzzon/sisyfos-audio-controller/commit/d2076b2379b5d80670f0293d11aa2970a78e03de)) +- support multiple mixers in Fade in-out ([b67c06d](https://github.com/olzzon/sisyfos-audio-controller/commit/b67c06da7b1f91e01326183951de2d4748a8a3b8)) + +### Bug Fixes + +- crash when starting with a pre 4.xx settings.json file ([35b7732](https://github.com/olzzon/sisyfos-audio-controller/commit/35b7732980dcb5fbbdcc1049431d087855f3c14f)) +- deep clone to new mixer added in settings ([dc077be](https://github.com/olzzon/sisyfos-audio-controller/commit/dc077be58350870b622957672f1018993e292bee)) +- limit VU updatespeed to 100ms for performance issues on large mixer setups ([858acf1](https://github.com/olzzon/sisyfos-audio-controller/commit/858acf1e0f72f1c74581352d9648ca886d02374a)) +- metering - possibly undefined (wasn´t discovered, as the metering previously wasn´t visible if it was undefined) ([9ee5094](https://github.com/olzzon/sisyfos-audio-controller/commit/9ee5094b27440559812bd3fe755c83551e082f78)) +- mixer online forced rerendering. Mixer Online i still only status for first mixer. (ToDO: support all mixers in GUI) ([622cc2e](https://github.com/olzzon/sisyfos-audio-controller/commit/622cc2e16c4760896ef1a003c7c928a27a8e5e1e)) +- multiple mixers - assign channels to fader only assigned first mixer ([2086754](https://github.com/olzzon/sisyfos-audio-controller/commit/2086754bc1d60ce2460832b0e9af8118a9eae1e3)) +- multiple mixers - aux settings support for first mixer - ToDo: support multiple mixers ([921be2d](https://github.com/olzzon/sisyfos-audio-controller/commit/921be2d516255e7f51123ee115f451c7d93f5d8a)) +- multiple mixers - update mixer number of mixers - ch datastructure problem ([9b3642a](https://github.com/olzzon/sisyfos-audio-controller/commit/9b3642acbab86b04b46902e4f88c30d30c662864)) +- multiple mixers, mixerconnection reference to correct mixer instead of first one ([59dee5d](https://github.com/olzzon/sisyfos-audio-controller/commit/59dee5dbef36b7e2b64c78e3b63401e5db14e066)) +- multple mixers settings - port aux etc didn´t update correctly ([d87bc77](https://github.com/olzzon/sisyfos-audio-controller/commit/d87bc77dc123f417b1f4c6e66b3b8e499892c9bf)) +- OSC protocol - type in logger.info mixerport ([b95e3c8](https://github.com/olzzon/sisyfos-audio-controller/commit/b95e3c8fb3cfab18c6d00852877f4852d03a92d4)) +- re-render issue in miniChannels mixer ([a1fb85f](https://github.com/olzzon/sisyfos-audio-controller/commit/a1fb85f55298f38f9547ee8e20c1e3c22ce3ffdf)) +- typo - CHANNEL_ACTIONS constant was left over in SettingsStorage.ts ([91905a9](https://github.com/olzzon/sisyfos-audio-controller/commit/91905a97dcae750f20d2aa5464665a35b5888dd9)) + +### [3.6.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v3.6.0...v3.6.1) (2020-08-13) + +### Bug Fixes + +- OSC (Behringer - Midas) protocol use internal 0-1 level when sending level to mix parameters ([4998ae1](https://github.com/olzzon/sisyfos-audio-controller/commit/4998ae1101897a321ab325d640f7662b6eed8ff0)) + +## [3.6.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v3.5.0...v3.6.0) (2020-08-12) + +### Features + +- add CHANNEL_INPUT_GAIN in mixer protocols ([729dcb5](https://github.com/olzzon/sisyfos-audio-controller/commit/729dcb5428a58fd5ece790d8fa221c39cdab2160)) +- Behringer XR protocol - remove unused variables. ([3981afc](https://github.com/olzzon/sisyfos-audio-controller/commit/3981afc21b8a751953719cbde576abfd7cd68976)) +- Chan Strip show/hide only Comp-Delay-Eq parts that are in selected mixerprotocol ([167318e](https://github.com/olzzon/sisyfos-audio-controller/commit/167318ec04680669bc97ff97b94ff8fc36aa3c65)) +- channel strip follows PFL ([3f3b867](https://github.com/olzzon/sisyfos-audio-controller/commit/3f3b8679fd14a14e4b25397f3b0cb05dd28d8d80)) +- disabled faders (from protocol) ([e02410b](https://github.com/olzzon/sisyfos-audio-controller/commit/e02410b1e190bbbbbd51732ec69d68acc5dd1d86)) +- feedback for input sel, gain and pages ([da57f6a](https://github.com/olzzon/sisyfos-audio-controller/commit/da57f6ac1b2ff27eda47cae6d6c73773139b3f47)) +- flexible UI layout, AutoMix, Capabilities (and more) ([c210c0e](https://github.com/olzzon/sisyfos-audio-controller/commit/c210c0e80cc5214f057f3657b0a185277ccd80a3)) +- input gain and selector - input gain implemented - selector GUI prepared ([1e8b550](https://github.com/olzzon/sisyfos-audio-controller/commit/1e8b55083b7366737215f6bb6de78b49e7afb0b1)) +- input selector - added CHANNEL_INPUT_SELECTOR in mixer protocol ([04e6c61](https://github.com/olzzon/sisyfos-audio-controller/commit/04e6c61505bf711c4306df835c8f6bf333fe8e60)) +- pages ([8c5b212](https://github.com/olzzon/sisyfos-audio-controller/commit/8c5b2129527ccccc030ab973ca21634fa4c326cc)) +- **Lawo Ruby:** channel to source mappings ([0fde375](https://github.com/olzzon/sisyfos-audio-controller/commit/0fde375e9737af2fd258eb15246f8a7264fe3f84)) +- input selector - implemented ([419c1be](https://github.com/olzzon/sisyfos-audio-controller/commit/419c1becd1a95e797d779b2862e1e0eff37cb0c7)) +- Inputselector buttons and Gain is only visible when added to mixerprotocol. ([7d69ef7](https://github.com/olzzon/sisyfos-audio-controller/commit/7d69ef76e465904e053b476bc47866729a6ca95f)) +- lawo ruby gain + input select ([d5b552c](https://github.com/olzzon/sisyfos-audio-controller/commit/d5b552c277a64ac2921e6a27fefa59526e385ddb)) +- Midas/Behringer X32 - mixer protocol cleanup - removed unused variables ([71509ac](https://github.com/olzzon/sisyfos-audio-controller/commit/71509ac8d962a5104857ce3495ee992a65cb05fe)) + +### Bug Fixes + +- align Channels selector and Delay buttons ([252face](https://github.com/olzzon/sisyfos-audio-controller/commit/252face617b584be1087900b271beb3416a29b74)) +- correct mutation type ([0de941d](https://github.com/olzzon/sisyfos-audio-controller/commit/0de941d4b043ce875e561687cee2b75544091584)) +- crash when .presetFileExtension was not present in mixerprotocol ([616c954](https://github.com/olzzon/sisyfos-audio-controller/commit/616c954fca511ca06da9fe33c45645739cb0ae43)) +- css - "Load mixer preset" was not centered ([0dac1e7](https://github.com/olzzon/sisyfos-audio-controller/commit/0dac1e77b7443491eca80c0a4d514977748d3c6a)) +- initial fixes for working Lawo Ruby + upgrade emberplus-conn ([8c556a5](https://github.com/olzzon/sisyfos-audio-controller/commit/8c556a547a963d8efdeba97f25cb93701836106c)) +- lawo ruby subscriptions ([4b3f4a6](https://github.com/olzzon/sisyfos-audio-controller/commit/4b3f4a65dcc04e5318006a97d936add0e82db505)) +- SSL - don´t update received fader level if value is identical to current value (when assigning more than 1 channel pr fader in Sisyfos) ([6ba6078](https://github.com/olzzon/sisyfos-audio-controller/commit/6ba6078366be56da66841a9554084d81b15291b9)) +- **Lawo Ruby:** misc fixes ([b1744da](https://github.com/olzzon/sisyfos-audio-controller/commit/b1744daa057a7bddb22f1bd6ea7aad4c4583f23a)) +- wrong constant for store dispath (used SOCKET instead of reducer) ([0cdb455](https://github.com/olzzon/sisyfos-audio-controller/commit/0cdb45556079c0b86a4cf6c366681b370b20f74a)) +- X32 - mixer was offline when receiving data for a channel with a higher assigned fader than total amount of faders ([0a38821](https://github.com/olzzon/sisyfos-audio-controller/commit/0a388216e2b19b6619591216444ce0d60428a7f1)) + +## [3.5.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v3.4.0...v3.5.0) (2020-06-08) + +### Features + +- List mixer presets in storage prepared ([67b6435](https://github.com/olzzon/sisyfos-audio-controller/commit/67b643522ab7cec9635b7e2566ca7123115b1239)) +- load mixer preset - Load scene from X32 ([7f1eb77](https://github.com/olzzon/sisyfos-audio-controller/commit/7f1eb775bcfe00e554e1b5417ece977fd6bb26d5)) +- load mixer preset - prepared protocols with loadPresetCommand.mixerMessage ([4ffbf3c](https://github.com/olzzon/sisyfos-audio-controller/commit/4ffbf3cb7e53bbf22fc45018def9606fc2027fa1)) +- load mixer preset - update examples ([53581c3](https://github.com/olzzon/sisyfos-audio-controller/commit/53581c3f3559ec30a53191fa2996648db5a73e90)) +- load mixer preset - x32 example files added ([260a71d](https://github.com/olzzon/sisyfos-audio-controller/commit/260a71d7085b1f7bc6e75d8e49e1988c193ba821)) +- Localization - simple localization for Sisyfos ([85a3442](https://github.com/olzzon/sisyfos-audio-controller/commit/85a344214e85dac059e7b2571ec2d66e587afc6f)) +- localization add nb and sv ([7431031](https://github.com/olzzon/sisyfos-audio-controller/commit/74310318942d436bbb0aa508ed7bba741951fdb4)) +- mixer-preset-loading working Midas/Behringer X32 preset loading ([a8fe1a9](https://github.com/olzzon/sisyfos-audio-controller/commit/a8fe1a97fe842716adc403bcffd9a9c0f92dbdc0)) + +### Bug Fixes + +- compressor area in chan strip was scrollable in css. ([55bc40a](https://github.com/olzzon/sisyfos-audio-controller/commit/55bc40af3f8e597217a035f64c923cdad15cbd42)) +- missing declaration in protocol ([74524c4](https://github.com/olzzon/sisyfos-audio-controller/commit/74524c4b241eebd9385d7f5be3bb3dc5332f1fec)) +- mixer-preset compare both sides as uppercase ([0617fec](https://github.com/olzzon/sisyfos-audio-controller/commit/0617fec84567bca0e7d71e72dfcd89fb568e7af3)) +- mixer-preset-list check files as uppercase ([ac97d70](https://github.com/olzzon/sisyfos-audio-controller/commit/ac97d70647b54bc6eeac06af83ee9a3fe2126f65)) + +## [3.4.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v3.3.0...v3.4.0) (2020-06-01) + +### Features + +- **casparcg:** adds CasparCG monitoring support for NEXT/PST ([d072336](https://github.com/olzzon/sisyfos-audio-controller/commit/d0723367275b31cc54599068b4eb70e00a6e0a75)) + +### Bug Fixes + +- metering should come from the first assigned channel (until multi channel metering is available) ([2c01de9](https://github.com/olzzon/sisyfos-audio-controller/commit/2c01de9a7fbd70cbd6bc57a0d9d170b1efccfe92)) +- Midas - Behringer X32 - emit all meter values in one blob ([e5fd8a9](https://github.com/olzzon/sisyfos-audio-controller/commit/e5fd8a97b5e0b623f1c8bf7ae2a1465fe7069538)) +- midas - ensure a number when creating new array ([f63003a](https://github.com/olzzon/sisyfos-audio-controller/commit/f63003a78b062a0d437db44ad8d520b5fae91d5d)) +- midas - wrong logic in checking for unavailble faders ([eb3a178](https://github.com/olzzon/sisyfos-audio-controller/commit/eb3a17850192b44c80133490b2ea755fbb90cb1a)) +- midas - x32 metering was pr channel not pr assignedFader ([47b54d2](https://github.com/olzzon/sisyfos-audio-controller/commit/47b54d20ada009d2094f543a6f6b1e9715bffe6d)) +- midas optimize - do not assigned meters for more than number of faders (no matter of assignment) ([711d240](https://github.com/olzzon/sisyfos-audio-controller/commit/711d24070bce22b2c3436ed1c679420545279650)) +- Reduction meter showed reverse value (max reduction when none, and min when max) ([a1aa3eb](https://github.com/olzzon/sisyfos-audio-controller/commit/a1aa3ebbee84759afaac0e1a7553f5f7debf59b7)) +- rename Gain red. to "reducition" for fint size/space on Windows machine. ([2601cf7](https://github.com/olzzon/sisyfos-audio-controller/commit/2601cf75a66fdfa3d74f0a26766aa5d31cf6f4a8)) +- smaller top margin on Reduction meter ([ebf3cc3](https://github.com/olzzon/sisyfos-audio-controller/commit/ebf3cc37a89a473b6b729d849c5040d190361ca1)) + +## [3.3.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v3.2.0...v3.3.0) (2020-05-11) + +### Features + +- Studer 2-way control - mono - stereo - 51 fader level working ([d2a38b2](https://github.com/olzzon/sisyfos-audio-controller/commit/d2a38b27fec46596a77bf24f297bf1b1f7dfcf48)) +- Studer fader level return - level values alligned to/from Sisyfos ([68781b1](https://github.com/olzzon/sisyfos-audio-controller/commit/68781b1ef9a1346bc6fe2d6d931b85dd42daa52a)) +- Vista - 2 way protocol - initial fader level support for mono channels ([d856688](https://github.com/olzzon/sisyfos-audio-controller/commit/d85668819bfbcf48101b2dcd64ec5121ae4076b2)) +- Vista - 2way MUTE support ([f01291b](https://github.com/olzzon/sisyfos-audio-controller/commit/f01291b451fcce6a7eac8f13de44918ddda89180)) +- Vista - Aux level 2-way ([ab835d6](https://github.com/olzzon/sisyfos-audio-controller/commit/ab835d6d68a39bdcb57953bf735ea627f6c54443)) +- vista - get initial mute state ([3f5306e](https://github.com/olzzon/sisyfos-audio-controller/commit/3f5306e74462fc37899acb26ed53b2ceb9524e92)) +- Vista - receive mixers fader level for mono channels ([f73a981](https://github.com/olzzon/sisyfos-audio-controller/commit/f73a9818429516bf70077eec27a7c565ce4723d5)) +- vista - subscribe to Aux sends when connecting ([d62dd6d](https://github.com/olzzon/sisyfos-audio-controller/commit/d62dd6da118c5c9cfb2f5751f8b3dd0d9338f24a)) +- vista preparing 2-way sopport ([6b6ec5a](https://github.com/olzzon/sisyfos-audio-controller/commit/6b6ec5aec7d2fe32ab1994ff78ab65991b1a741f)) + +### Bug Fixes + +- emit current settings to client and not the stored one. ([a4a1074](https://github.com/olzzon/sisyfos-audio-controller/commit/a4a1074c08f89dc30af2fefe9faa41808ba8bb46)) +- update all channels in channelReducers->SET_COMPLETE_CH_STATE ([9b3aea7](https://github.com/olzzon/sisyfos-audio-controller/commit/9b3aea760d374320a73cc2efd5a8780bb7d2c00c)) + +## [3.2.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v3.1.0...v3.2.0) (2020-05-07) + +### Features + +- skaahoj - monitor panel mixer ([5390723](https://github.com/olzzon/sisyfos-audio-controller/commit/53907231e71ad27fa1bb30d3c271ea240a252083)) +- Skaarhoj - abstract remote controllers for other support that HUI ([ee6384e](https://github.com/olzzon/sisyfos-audio-controller/commit/ee6384ef383b8766d8bddb06acbd7a8ea435e236)) +- Skaarhoj - further refatoring to prepare support ([999aafb](https://github.com/olzzon/sisyfos-audio-controller/commit/999aafbe94c3add38661613c4aceb50168dcb7de)) +- skaarhoj - mapping used for assigning to faders. hwc[#1](https://github.com/olzzon/sisyfos-audio-controller/issues/1) <> fader 1 etc ([6821c22](https://github.com/olzzon/sisyfos-audio-controller/commit/6821c2257cb29f8ee3075355076a54cb556a04ad)) +- skaarhoj - set display values on initial connection ([2534b89](https://github.com/olzzon/sisyfos-audio-controller/commit/2534b89d1eade478eb5094b02c370f7406b53587)) +- skaarhoj init server and load at server startup ([6123142](https://github.com/olzzon/sisyfos-audio-controller/commit/61231420e03cd78f51a845a8c65e176d655e61cd)) +- skaarhoj monitor mix% control on hwc[#81](https://github.com/olzzon/sisyfos-audio-controller/issues/81)-89 91 101 ([24817b6](https://github.com/olzzon/sisyfos-audio-controller/commit/24817b66577d40becd072f62a2694b2b1656ef2c)), closes [hwc#81-89](https://github.com/olzzon/hwc/issues/81-89) +- skaarhoj panel level support on rotary ([93ad7fe](https://github.com/olzzon/sisyfos-audio-controller/commit/93ad7fe3435a555f36a99545dbdec8535c76d72e)) + +### Bug Fixes + +- adding files for last commit ([331d61a](https://github.com/olzzon/sisyfos-audio-controller/commit/331d61abb49853650e09d16c2eb893537e14981b)) +- Mixer Online did not turn red when connection was lost - fixed on OSC protocols and on Vista mixer ([52c429d](https://github.com/olzzon/sisyfos-audio-controller/commit/52c429d79574f5c467711389d971a1ca1e5fd2cd)) +- only allow 9 aux sends pr monitor output - update readme ([316501c](https://github.com/olzzon/sisyfos-audio-controller/commit/316501c3fa742085a66bed86c454c11023ad9bff)) +- skaarhoj - handling error when lost connection to client ([2393d5f](https://github.com/olzzon/sisyfos-audio-controller/commit/2393d5f3bd0f061fc04b4e76e9bcdeaa97713005)) +- skaarhoj rotary enc handle fast rotary ([e554b8a](https://github.com/olzzon/sisyfos-audio-controller/commit/e554b8aeb73aafab017537fa2368cd053936d115)) + +## [3.1.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v3.0.0...v3.1.0) (2020-04-27) + +### Features + +- husky and lint-stages setup ([ac99595](https://github.com/olzzon/sisyfos-audio-controller/commit/ac995955b0216d50e58327acc7629b2118c49851)) +- Vista - support for NEXT-CUE and MUTE on Mono, Stereo and 5.1 channels ([9da7cdf](https://github.com/olzzon/sisyfos-audio-controller/commit/9da7cdfc0c0fa95bcd3e347753cff911b669eaa8)) +- Vista Next-Aux send level and Mute for the mono channels ([7757ff2](https://github.com/olzzon/sisyfos-audio-controller/commit/7757ff2d63445c8c7ca017ad4ff760292a21b6b1)) + +### Bug Fixes + +- Studer Vista - better logarithmic support ([d2fa070](https://github.com/olzzon/sisyfos-audio-controller/commit/d2fa070131518316dfbe1a77d5717e184406bb83)) + +## [3.0.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.13.0...v3.0.0) (2020-04-24) + +## [2.13.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.12.0...v2.13.0) (2020-04-24) + +### Features + +- Behringer X32 gain reduction meter ([c0e3469](https://github.com/olzzon/sisyfos-audio-controller/commit/c0e3469a48965542487b0e10e3561c603aabe268)) +- Behringer XR & Midas MR series Gain reduction. (rest of ch strip to be implemented) ([c81a7f4](https://github.com/olzzon/sisyfos-audio-controller/commit/c81a7f417188a082cd6d56f841baf7c707a1ceaa)) +- Behringer XR-Midas MR support mute-eq,comp,aux ([9df30ba](https://github.com/olzzon/sisyfos-audio-controller/commit/9df30bacd3c22050d13ba8352fe26fbc33c19a41)) +- Gain reduction meter & preparing Behringer XR protocol ([17510ab](https://github.com/olzzon/sisyfos-audio-controller/commit/17510abb784eda1cef9b1d328559b07ad0413ef6)) +- Vista 1-5-9 support fader level from Sisyfos on mono, st, and 5.1 channels ([5cf60b4](https://github.com/olzzon/sisyfos-audio-controller/commit/5cf60b4dd3282a4ad88a3feabbb358780fc29fff)) + +### Bug Fixes + +\* + +- check if fader exists before requesting from mixer ([8c06344](https://github.com/olzzon/sisyfos-audio-controller/commit/8c06344a57285e215ae282aa872bf40c9963eb30)) +- reduction meter middler and upper rendering ([589d936](https://github.com/olzzon/sisyfos-audio-controller/commit/589d9365aa143c6fe348fd840647f288bda4ad36)) +- update Next Aux level in OSC protocol (behringer, Midas etc.) ([38a6ec7](https://github.com/olzzon/sisyfos-audio-controller/commit/38a6ec7ccff31953413ec273908832f263758d16)) +- update Next aux when changing fader level while it´s on ([2480904](https://github.com/olzzon/sisyfos-audio-controller/commit/248090484177d70e665aa42ff26335d9b372ed0a)) +- when receiving aux level, only set it of aux is assigned in sisyfos (to be able to only control the ones that the use should control and not all) ([afcc4cd](https://github.com/olzzon/sisyfos-audio-controller/commit/afcc4cdf6267e05371c27556385fa75a1b31ff85)) + +## [2.12.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.11.0...v2.12.0) (2020-04-02) + +### Features + +- Studer - handle up to 95 channels on OnAir 3000. Prepare Vista handling ([9c50bba](https://github.com/olzzon/sisyfos-audio-controller/commit/9c50bbab7876624130c74d15cfc0233b14c36936)) +- Studer Vista ([baa248e](https://github.com/olzzon/sisyfos-audio-controller/commit/baa248e58deb532b0f62a182692512cb47713c85)) +- Vista 1-5-9 Encoding Mono channels including level (using BER) ([ca05cb3](https://github.com/olzzon/sisyfos-audio-controller/commit/ca05cb317686399aa6e7ca9b26461c4d59824f30)) +- vista support for mono, stereo and 51 channels ([33633e7](https://github.com/olzzon/sisyfos-audio-controller/commit/33633e7bd89ee9cab38bb75c937220a1425ad943)) + +### Bug Fixes + +- **CasparCG:** Fixes VU meters for CasparCG ([1899d1f](https://github.com/olzzon/sisyfos-audio-controller/commit/1899d1f6ba0beb8b68012122e176b9d023d1c892)) +- **CasparCG:** Typo fix in ccg route source ([fb0c0f8](https://github.com/olzzon/sisyfos-audio-controller/commit/fb0c0f84cfa7a104e3c50d2af71ea8171a10b962)) +- chan strip refered to channeltype when label was empty ([b996d63](https://github.com/olzzon/sisyfos-audio-controller/commit/b996d632debd657f3871bf482093eba3748ee07e)) +- double import of sockerServer in CasparCGConnection.ts forgot to remove in merge ([cbc2ebe](https://github.com/olzzon/sisyfos-audio-controller/commit/cbc2ebe2c8bf104c0ff16238b8cd40128e508841)) +- faders should not overlap buttons ([d976aa3](https://github.com/olzzon/sisyfos-audio-controller/commit/d976aa324e6033c32b0d123a1d1bdf54c000137b)) +- prevent scrolling of parent when in an iframe ([bb48c54](https://github.com/olzzon/sisyfos-audio-controller/commit/bb48c54d8bb2d5b8489b8e894188eb705610f7e3)) +- Studer update faders with log scale ([a6e1b24](https://github.com/olzzon/sisyfos-audio-controller/commit/a6e1b241ae99ef080ff7898bd6a06aaaccee11f5)) +- update yarn to support BER in Vista mixer connection ([722dc5d](https://github.com/olzzon/sisyfos-audio-controller/commit/722dc5d3c062cf6c40e700e0fb1c8fe70d85fab3)) +- when dragging a fader mouseUp could trigger other buttons. ([145423e](https://github.com/olzzon/sisyfos-audio-controller/commit/145423e9a02e7ea6942b829eff1c18f6f4164f31)) + +## [2.11.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.10.1...v2.11.0) (2020-03-25) + +### Features + +- Studer OnAir support ([02acbbe](https://github.com/olzzon/sisyfos-audio-controller/commit/02acbbe7343aab2edfb069816e25a060fe51fc95)) +- Studer support - basic level for OnAir3000 ([b7ca75f](https://github.com/olzzon/sisyfos-audio-controller/commit/b7ca75f9cb57ef0f5dd42ce8be8401a381e0d59a)) +- **CasparCG:** adds route producer as source ([7d8aaf2](https://github.com/olzzon/sisyfos-audio-controller/commit/7d8aaf29a992847855e2a3f18262414d796277b0)) +- **Server:** Adds logline on server address on startup ([fe87c65](https://github.com/olzzon/sisyfos-audio-controller/commit/fe87c653fe7e26df5a01038bf44be7710b121076)) + +### Bug Fixes + +- comment out unused in studer protocol ([0219964](https://github.com/olzzon/sisyfos-audio-controller/commit/02199645a6ca2a4bbb33724febed68760fbea10c)) +- **CasparCG:** Compatibility between Decklink and Route sources ([4b3c63d](https://github.com/olzzon/sisyfos-audio-controller/commit/4b3c63d3e694f279fe8c6baef56691c21c0d0bbe)) +- **CasparCG:** Compatible with CCG Server 2.1.11.NRK route producer ([a39edcb](https://github.com/olzzon/sisyfos-audio-controller/commit/a39edcb914ec46a653a5758cb0802701f4b777f3)) +- changed logger.info to logger.error in casparCGConnection ([ec1fc67](https://github.com/olzzon/sisyfos-audio-controller/commit/ec1fc670e4a87349577ae52bd94dc5bae7ae621a)) + +### [2.10.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.10.0...v2.10.1) (2020-03-24) + +### Bug Fixes + +- changed logger.info to logger.error in casparCGConnection ([5541b94](https://github.com/olzzon/sisyfos-audio-controller/commit/5541b9442ccf3d918be4b2ae5c5e977556ba1ea7)) +- Client indicate when server is offline ([5ec04a7](https://github.com/olzzon/sisyfos-audio-controller/commit/5ec04a7bdfd0fe70209505a55257a27cdd47130e)) +- rename "Offtube mode" to "Eq-Comp-Aux in chstrip" ([1b10cb4](https://github.com/olzzon/sisyfos-audio-controller/commit/1b10cb4953dad6f30602ab876aad8229c638db00)) +- show CasparCG source select no matter whether Offtube Mode is selected ([696dfed](https://github.com/olzzon/sisyfos-audio-controller/commit/696dfed45f2a9e280a35d168a54c8cc899213bf7)) + +## [2.10.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.5...v2.10.0) (2020-03-19) + +### Features + +- change emberplus to other repo ([e50b9b7](https://github.com/olzzon/sisyfos-audio-controller/commit/e50b9b7ff0cf967bb451836a31790bb5a3feba9d)) +- ember - make dedicated sendOutLevelMessage instead of a generic one where you have to do a getElementByPath each time ([4034bf5](https://github.com/olzzon/sisyfos-audio-controller/commit/4034bf59f5c06f665ac34ea5376831fb6c883142)) +- Ember - use timeout-hack for better Lawo support ([2b508f2](https://github.com/olzzon/sisyfos-audio-controller/commit/2b508f21b5d958341bda4910b82cdf3804d81f03)) +- Ember connection set up differently ([bc6c6bd](https://github.com/olzzon/sisyfos-audio-controller/commit/bc6c6bd4682a14989c6852928f3869d28ba2451b)) +- Ember Lawo - use master branch on https://github.com/dufourgilles/node-emberplus.git ([54eb20a](https://github.com/olzzon/sisyfos-audio-controller/commit/54eb20a99af4c3baee958f151dc74cdd73b93cc4)) +- FADE_DISPATCH_RESOLUTION constant are moved to protocol to enable fever commands on slow protocols ([18fd425](https://github.com/olzzon/sisyfos-audio-controller/commit/18fd42539789a23a0f4613c6868e73b36fa01a20)) +- lawo-mc - add files for last commit ([e29831f](https://github.com/olzzon/sisyfos-audio-controller/commit/e29831fc05e0c9b5cd8639c460244e1e15a4c091)) +- lawo-mc - create LawoMC protocol. (not configures yet) ([7d963a5](https://github.com/olzzon/sisyfos-audio-controller/commit/7d963a52918203df44a01f63e7d62302005bcd79)) +- Lawo-MC fader level added to protocol. ([ad26a6b](https://github.com/olzzon/sisyfos-audio-controller/commit/ad26a6bff9e27bf5e93657f4d55e6c1de416b8d4)) +- LawoRuby - initial protocol ([d96533d](https://github.com/olzzon/sisyfos-audio-controller/commit/d96533d6f5c1633719b8875b223838283d9cd3c7)) +- minimonitorview - css tweaks ([db5d617](https://github.com/olzzon/sisyfos-audio-controller/commit/db5d617e751f0d3ffb7437eb0f75476cb7707bc1)) +- minimonitorview - label in monitor settings ([60b6a4c](https://github.com/olzzon/sisyfos-audio-controller/commit/60b6a4cf08652764132b59c4d3ae4c622f06a1a9)) +- monitorview - settings in monitor setup, stored server side ([8837fce](https://github.com/olzzon/sisyfos-audio-controller/commit/8837fceeeb29fc007a3740d252a1de33126a77d6)) + +### Bug Fixes + +- casparCGMaster protocol should not be able to be undefined (a template is always loaded) ([477549e](https://github.com/olzzon/sisyfos-audio-controller/commit/477549e88b0e7886dd905103df08ebde263b59c3)) +- internal levels are always 0-1 conversion to protocol level must take place in the protocols mixerconnection ([88dd14f](https://github.com/olzzon/sisyfos-audio-controller/commit/88dd14f392f407a229e0fa4163f64b36076b9d79)) + +### [2.9.5](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.4...v2.9.5) (2020-02-16) + +### Bug Fixes + +- add preventDefault in onthouchEnd on vo, mute and auto buttons too ([245352a](https://github.com/olzzon/sisyfos-audio-controller/commit/245352a11e1c1b35a7b8d37711ce66c9e82ae838)) + +### [2.9.4](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.3...v2.9.4) (2020-02-15) + +### Bug Fixes + +- always clear fade timer before setting a new one ([028d666](https://github.com/olzzon/sisyfos-audio-controller/commit/028d66620b81c090d2b12f1c0ffb19bdb0e45f67)) +- avoid crash of Sisyfos when selecting Lawo and Studer premilary protocols ([d130205](https://github.com/olzzon/sisyfos-audio-controller/commit/d13020572f0f83d0b3d7869d6121eaaed9a82b87)) + +### [2.9.3](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.2...v2.9.3) (2020-02-14) + +### Bug Fixes + +- handling of touch on pgm-vo-mute-auto buttons without the need for /?multitouch=1 ([d58fd1b](https://github.com/olzzon/sisyfos-audio-controller/commit/d58fd1b5bebb51659dd1b29057540ca4b2cdb3e9)) + +### [2.9.2](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.1...v2.9.2) (2020-02-14) + +### Bug Fixes + +- prevent floating point loop on fader level by setting step to 0.01 ([263d016](https://github.com/olzzon/sisyfos-audio-controller/commit/263d0162e4163cd4b866afe88d50601df23ef8c1)) + +### [2.9.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.9.0...v2.9.1) (2020-02-14) + +### Bug Fixes + +- color of fader-handle dependent on pgm-vo-mute state ([5796eec](https://github.com/olzzon/sisyfos-audio-controller/commit/5796eeca8209a2f171e8a1cfa4ff9a33d3bdd0b2)) +- don´t toggle both on touch & click if multitouch is off ([1b46a47](https://github.com/olzzon/sisyfos-audio-controller/commit/1b46a47218eaa7f879ebe9c2c0e65bacc7effbbe)) +- Fader level was reversed (1-0 instead of 0-1) ([4932128](https://github.com/olzzon/sisyfos-audio-controller/commit/4932128a2ed394a3105eba71e9d12a2f5d79c088)) +- update fader handle color on state shift ([e149456](https://github.com/olzzon/sisyfos-audio-controller/commit/e14945687690a1b309a1f557d0221e6ce370b597)) + +## [2.9.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.8.0...v2.9.0) (2020-02-12) + +### Features + +- multitouch - add css file. set animate to false for better multiclient multitouch support ([5ed9596](https://github.com/olzzon/sisyfos-audio-controller/commit/5ed95962a4434986c47f1b5b3c32291ed11904cc)) +- multitouch - added styling, moved ChanStrip params back to single touch (using react-slider) ([313089e](https://github.com/olzzon/sisyfos-audio-controller/commit/313089e4a02fe6c80962b3c8892368d34ec7ebcf)) +- multitouch - move to NoUISlider to support multitouch. ToDo CSS ([b59d230](https://github.com/olzzon/sisyfos-audio-controller/commit/b59d230d887ae100b8bd3d3d0882571171dbdefe)) +- multitouch - supporteded on pgm, vo, mute and auto buttons. ([7921d9b](https://github.com/olzzon/sisyfos-audio-controller/commit/7921d9b227177c36b0e143d759d714b8076731a5)) + +## [2.8.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.7.1...v2.8.0) (2020-02-11) + +### Features + +- implement Sofie iFrame support ([a96215a](https://github.com/olzzon/sisyfos-audio-controller/commit/a96215a9675de754296f07d3b0bb06378e2fc6e3)) +- Sisyfos inside iFrame. Use window.top !== window.self to chech if it´s running inside something ([76ceca9](https://github.com/olzzon/sisyfos-audio-controller/commit/76ceca9a193ae2025b649bef83a669879eac952e)) +- Sisyfos running in iFrame. Use frameElement instead of checking parent. ([bcc3633](https://github.com/olzzon/sisyfos-audio-controller/commit/bcc3633e016b6b9ea7afaaf702500b92ae4b0ea6)) + +### [2.7.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.7.0...v2.7.1) (2020-02-07) + +## [2.7.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.6.0...v2.7.0) (2020-02-05) + +### Features + +- Channelstrip Delay Time generic implementation ([0a5a88c](https://github.com/olzzon/sisyfos-audio-controller/commit/0a5a88ccc3dd3ebbb413d364b084153d7b4cdaf8)) +- chanStrip delaybuttons to fineadjust delay value ([7ee1418](https://github.com/olzzon/sisyfos-audio-controller/commit/7ee1418aa5782999daee8f8dcf95880d436a7de7)) +- chanStrip slide in-out fdrom left ([983cefb](https://github.com/olzzon/sisyfos-audio-controller/commit/983cefb1fd2f3a0906c2d7ab737864ec9900e057)) +- disable label transfer to Midas so Sofie can set userlabels in Sisyfos without interfering with the mixer labels ([0e139eb](https://github.com/olzzon/sisyfos-audio-controller/commit/0e139ebba17c651f5ef7bccd6b7d8e7b84dfc347)) +- Midas receive delayTime state ([de94606](https://github.com/olzzon/sisyfos-audio-controller/commit/de94606eb90d26b74da8160b5a9a3bb2fc5a3a1d)) +- Midas/X32 MUTE button support ([e922d5f](https://github.com/olzzon/sisyfos-audio-controller/commit/e922d5f36c385f81536091649a28ed5f4fab5633)) +- offtube mode, make channelstrip area persistent. ([aebb505](https://github.com/olzzon/sisyfos-audio-controller/commit/aebb505457d7ad58bf510157fd8230b4b341077f)) +- wider chanstrip for support of more aux sends ([f6872db](https://github.com/olzzon/sisyfos-audio-controller/commit/f6872dbcd5eeb5196a41f311fdb7b54b7cfee4b7)) + +### Bug Fixes + +- chan strip - GUI compressor - delay header was 3 lines ([de6a733](https://github.com/olzzon/sisyfos-audio-controller/commit/de6a73317ef9eec8c140f3a61f09b34dd7dcc105)) +- loading storage with more channels than faders. (e.g. a fader controlling a 5.1 setup) ([93e10ec](https://github.com/olzzon/sisyfos-audio-controller/commit/93e10ec36cc98f3592b6fb10674ab2e8ee64544d)) +- Midas Delay param is between 0 and 1 not ms time ([e535722](https://github.com/olzzon/sisyfos-audio-controller/commit/e53572212d2e80de350e87c375d74fa2b9b61c70)) +- midas protocol missing DELAY_TIME ([12ac11c](https://github.com/olzzon/sisyfos-audio-controller/commit/12ac11c916096b7e7df3726f3319c04642aab018)) +- Type - Midas - fromMixer didn´t have the correct params ([87540f3](https://github.com/olzzon/sisyfos-audio-controller/commit/87540f3515305ad5c2f84349aa8f2df17cecbe2c)) + +## [2.6.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.5.0...v2.6.0) (2020-01-30) + +### Features + +- QL1 receive fader state working ([d434dd3](https://github.com/olzzon/sisyfos-audio-controller/commit/d434dd32ed89a05ef351f5ac5a2ae0ed7bcf5f8c)) +- QlCl - added mute support FROM Sisyfos ([8793170](https://github.com/olzzon/sisyfos-audio-controller/commit/8793170bba09cec80376531d5b13525fe7f39383)) +- yamaha QL - gain out command moved to protocol instead of hardwired in qlclconnection.ts ([e96f902](https://github.com/olzzon/sisyfos-audio-controller/commit/e96f9026dafb14df48caa2ce1deb8d825d23d14a)) +- Yamaha QL - use Winston logging instead of console.log ([d856e26](https://github.com/olzzon/sisyfos-audio-controller/commit/d856e26432e5ca9289e7fab448ef0d0cb3be9499)) +- yamaha QL1 - get MUTE state (on-off) from mixer ([ce021e9](https://github.com/olzzon/sisyfos-audio-controller/commit/ce021e9e3b5dce95e1eaba6ab2a50fb071705932)) +- yamaha qlcl - inital req of fader levels. - split buffers - 2 byte channel message ([f462841](https://github.com/olzzon/sisyfos-audio-controller/commit/f4628411784c9fb47d3c7349db8d43afe436c65a)) + +## [2.5.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.4.0...v2.5.0) (2020-01-29) + +### Features + +- CasparCGconnection.ts winston logger support ([4e0a7f0](https://github.com/olzzon/sisyfos-audio-controller/commit/4e0a7f055c3645eead11e567e28cc1c1e30f0858)) +- CCG channelsettings emit action for selecting new channel inputs. ([6f807cd](https://github.com/olzzon/sisyfos-audio-controller/commit/6f807cdda018513fd20418e55e587a4e844140e1)) +- CCG v2 show- PFL in settings replaces CUE NEXT ([9a24def](https://github.com/olzzon/sisyfos-audio-controller/commit/9a24defa5060853656ac46e54d992945bd32d9d8)) +- ccg-v2 - move config files to storage folder. ([53bd70e](https://github.com/olzzon/sisyfos-audio-controller/commit/53bd70e06d76d292cf84c94ff78165cbad25e055)) +- check geometry file for undefined ([b15fbb1](https://github.com/olzzon/sisyfos-audio-controller/commit/b15fbb15f2e02cea8a9ff5896b56ea43db16e151)) +- disable settings in browser by adding localhost:1176/?settings=0 ([f2dc03f](https://github.com/olzzon/sisyfos-audio-controller/commit/f2dc03f77ece5d2522ce54a4f7bb0370153fff8b)) +- load CasparCG settings from Storage menu ([c4e55e6](https://github.com/olzzon/sisyfos-audio-controller/commit/c4e55e6744d33a927b57f2c0e197f2dbe9c7f858)) +- move CasparCG input settings into channelstrip on left side ([7d20317](https://github.com/olzzon/sisyfos-audio-controller/commit/7d20317614a5bb508e29ebf8cd5ab8287f32803b)) +- only show Load CasparCG in Storage menu if there are any .ccg files ([6cda7c0](https://github.com/olzzon/sisyfos-audio-controller/commit/6cda7c0c8c51dda597542c586f6860e0daa92bf7)) +- Preparing CCG - /inject command so it´s possible pass a command directly from Sofie to Audiomixer. ([cb53eb5](https://github.com/olzzon/sisyfos-audio-controller/commit/cb53eb57ac2a322779b3bdecd95be040ea8e1b1e)) +- remove close button in CCG input settings window ([d61dab7](https://github.com/olzzon/sisyfos-audio-controller/commit/d61dab73f52a522e6edd60106f8f714c0db2d50b)) +- remove filehandling from mixerprotocol, include default example ([7918b05](https://github.com/olzzon/sisyfos-audio-controller/commit/7918b0573dd500c858f5e598fb50e373976f4d8e)) +- rename Storage menu to "STORAGE" ([ee917a2](https://github.com/olzzon/sisyfos-audio-controller/commit/ee917a2f9e50a62dba862aa00b609a480df95d7e)) +- set new CasparCG config from Storage Menu is working. ([7eab0b9](https://github.com/olzzon/sisyfos-audio-controller/commit/7eab0b90cc218636a41ffa2c7598661076cebc48)) +- set seperate loglevel for console with loggerConsoleLevel='verbose' updated in Readme.md ([beba900](https://github.com/olzzon/sisyfos-audio-controller/commit/beba90053efcf5c6efe8144ba07f1e7e1e66c17c)) + +### Bug Fixes + +- GUI crash for reference to fader label, on fader thats not defined. ([9bc4df7](https://github.com/olzzon/sisyfos-audio-controller/commit/9bc4df7f6f4c2753cb0c3933245a1aec9025ba21)) +- zero indicator on faders was off after new design ([78f48b5](https://github.com/olzzon/sisyfos-audio-controller/commit/78f48b5942a47a4393e490d6fadd0fa1fb558471)) + +## [2.4.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.3.3...v2.4.0) (2020-01-23) + +### Features + +- added Low-mid to get 4-band eq instead of 3-band eq ([59542a8](https://github.com/olzzon/sisyfos-audio-controller/commit/59542a83c1ca889696efe29fb4bc0d958567e77b)) +- chan strip zero indicators on eq, comp and monitor mix ([b9ec40e](https://github.com/olzzon/sisyfos-audio-controller/commit/b9ec40e16a2d6ff4c23fd457ff5a6ec4a9f73b87)) +- channel name in header of monitor mix minus ([99c0207](https://github.com/olzzon/sisyfos-audio-controller/commit/99c020743b641209423b924f042c6619c170321e)) +- get eq & comp state from Midas/Behringer X32 - both inital and realtime ([86bd216](https://github.com/olzzon/sisyfos-audio-controller/commit/86bd216d3e2cf4c15e241cdee6445e191f872d7a)) +- individual runtime args for setting log level of kibana and of local log file. ([e978093](https://github.com/olzzon/sisyfos-audio-controller/commit/e978093cae71699393493426b28d5aac450741ae)) +- Midas/Behringer OSC get inital Aux state from mixer ([7bb0741](https://github.com/olzzon/sisyfos-audio-controller/commit/7bb0741c2833274081d6f110d2b56876bcf5c33b)) +- move ch strip to left side ([89756b9](https://github.com/olzzon/sisyfos-audio-controller/commit/89756b9f39d9ec6715a8eac284690d977fa9e31a)) + +### Bug Fixes + +- Ardour ping mixewr command didn´t have osc data type ([b84e965](https://github.com/olzzon/sisyfos-audio-controller/commit/b84e965abf679d512eb7333543555485ec84123c)) +- channel-body css didn´t set heigth ([653def0](https://github.com/olzzon/sisyfos-audio-controller/commit/653def0d90f25210a61830aa0ef5f7b517bf0b2f)) +- delay initial state commands to avoid overload of OSC commands to Midas ([443325f](https://github.com/olzzon/sisyfos-audio-controller/commit/443325fc2179b6053271c92548ad64270b61f044)) +- Recived Midas Ratio has value from 0 to 11 and not 0 to 1 ([40afcc5](https://github.com/olzzon/sisyfos-audio-controller/commit/40afcc55d826c0f731f4c64e1f5698b167f0b4aa)) +- typo - dispatch obj with level: instead of label: ([e84abaa](https://github.com/olzzon/sisyfos-audio-controller/commit/e84abaa71671e8d77f0b47a7d6a459fa682717ab)) +- typo - don´t revert dispatch label from level: to label: ([974bec2](https://github.com/olzzon/sisyfos-audio-controller/commit/974bec262d84179a2c3893f979e2ebcdb9f1b715)) +- use .loMid value when updating loMid ([9c61686](https://github.com/olzzon/sisyfos-audio-controller/commit/9c61686a00385076a5764ff20249db50007e3a6d)) + +### [2.3.3](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.3.2...v2.3.3) (2020-01-15) + +### Bug Fixes + +- rename Label Monitor Mix to: "{FaderName} Monitor Mix Minus" ([d99a67b](https://github.com/olzzon/sisyfos-audio-controller/commit/d99a67b8499f3d21c14047a5ff612b684287ad0e)) +- update Auxlevel on mixer on changes ([08b832e](https://github.com/olzzon/sisyfos-audio-controller/commit/08b832eba9ac81c1a74e2de9b354103d05247b52)) + +### [2.3.2](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.3.1...v2.3.2) (2020-01-04) + +### [2.3.1](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.3.0...v2.3.1) (2020-01-01) + +### Bug Fixes + +- CI build errors ([d98475f](https://github.com/olzzon/sisyfos-audio-controller/commit/d98475f6b07381504c626f24394b4dbdacffd668)) +- create storage folder if not exists when trying to store settings for the first time ([41dcb09](https://github.com/olzzon/sisyfos-audio-controller/commit/41dcb09236e3768daa19fe64ce70499e769a0e1e)) +- do not use winston logger in contants files as they´re also used on client side ([fb2d847](https://github.com/olzzon/sisyfos-audio-controller/commit/fb2d84756d7330dfdf799f1269793d012ed0a195)) +- remove settings and default.shot from storage folder ([1c63eb2](https://github.com/olzzon/sisyfos-audio-controller/commit/1c63eb21933ce7414a405393b4c0564c80aace6f)) +- remove settings.json from server folder ([3229936](https://github.com/olzzon/sisyfos-audio-controller/commit/3229936a48c39765103204235a40935d92cb07e1)) + +## [2.3.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.2.0...v2.3.0) (2019-12-21) + +### Features + +- Ignore Automation implemented. A "MANUAL" button added in GUI so a fader can ignore commands from Automation ([1399711](https://github.com/olzzon/sisyfos-audio-controller/commit/1399711d9b1558702c5c305dc45b09fe82b2ea48)) + +### Bug Fixes + +- assign aux to fader use auxIndex instead of channel ([a9e3232](https://github.com/olzzon/sisyfos-audio-controller/commit/a9e3232b6a3fdeed9a3729aa7b09a1628931010d)) +- avoid clearing meters when setting full state of faders ([cce69f5](https://github.com/olzzon/sisyfos-audio-controller/commit/cce69f5c6da2b8b946f76f49b1f60ec9dbe0a501)) +- double code in AutomationConnection (had double check for X_MIX, Fade_to_black and visible) ([ff8af54](https://github.com/olzzon/sisyfos-audio-controller/commit/ff8af54c81bc4cff3ad8a8c04364e2d76a01ce52)) +- OscMixerConnection - compare whole command length ([876b367](https://github.com/olzzon/sisyfos-audio-controller/commit/876b3679ae772d6f3ebc2ddff608220c48beeeee)) +- Update GUI when state of muteOn and voOn is changed ([52bf3da](https://github.com/olzzon/sisyfos-audio-controller/commit/52bf3da1aa2ad2aa63ec2b03cc7fc6a4a0c97642)) + +## [2.2.0](https://github.com/olzzon/sisyfos-audio-controller/compare/v2.1.0...v2.2.0) (2019-12-18) + +### Features + +- mixer online - will restart server. ([fea6b24](https://github.com/olzzon/sisyfos-audio-controller/commit/fea6b24f897ee4a9e0e101fc45b5d1b92ed4227d)) + +### Bug Fixes + +- move storage to "storage" folder, to avoid docker conflicts ([7323ed9](https://github.com/olzzon/sisyfos-audio-controller/commit/7323ed9675b57dbff528a54dad93271099bda14d)) + +## 2.1.0 (2019-12-18) + +### Features + +- add channel settings UI ([8351cb0](https://github.com/olzzon/sisyfos-audio-controller/commit/8351cb05ffebf6aa2aa491023e3a5d2bd9b11287)) +- added protocol latency in settings. So setting "fadeActive" to false waits until last response from protocol. ([6d949ed](https://github.com/olzzon/sisyfos-audio-controller/commit/6d949edb988f741d63e91c0a34241c3eb8ab4cee)) +- Ardour adding meter support ([1864e3e](https://github.com/olzzon/sisyfos-audio-controller/commit/1864e3e88da2cfaa4db2d0c8e7332baef05591be)) +- Ardour meter support meter not meters ([9802ff5](https://github.com/olzzon/sisyfos-audio-controller/commit/9802ff5314b872fe6e5539ecdd78fe6fc9096128)) +- Ardour support - added channel name from mixer ([d767318](https://github.com/olzzon/sisyfos-audio-controller/commit/d76731868de78220070f70348cffc065083856dc)) +- Ardour support meter calimbration (loosely set) ([eb01418](https://github.com/olzzon/sisyfos-audio-controller/commit/eb014183fdf8bc3ab3bd66bf390fbf4959e66dcc)) +- CasparCG support as audio mixer ([#35](https://github.com/olzzon/sisyfos-audio-controller/issues/35)) ([d47cf5b](https://github.com/olzzon/sisyfos-audio-controller/commit/d47cf5bb018d6f7cab8b6d6b806a84d1c60511a5)) +- change VU meter rendering to canvas-based ([ee829d7](https://github.com/olzzon/sisyfos-audio-controller/commit/ee829d7960a0849826c2e90b459fcd760836b5a0)) +- Channel labels - protocol now support setting labels on mixer ([751b812](https://github.com/olzzon/sisyfos-audio-controller/commit/751b812d407d622b4fbd4d38f07ad167e3e2daac)) +- ChannelType added to IChannel in channelsReducer so each channel can reference to a channel type ([995b99e](https://github.com/olzzon/sisyfos-audio-controller/commit/995b99e26da34a20a5bf1663a504f14554cc2e51)) +- ChannelTypes - Channel color and label injected from mixerprotocol ([9552320](https://github.com/olzzon/sisyfos-audio-controller/commit/9552320e068008184cfb029fa8f5e226ebfa7ed3)) +- channelTypes - Ember+ level and gain implemented ([5f2752f](https://github.com/olzzon/sisyfos-audio-controller/commit/5f2752fe0f7aa0eda7ce7f98fe32a32f0bc63dc4)) +- ChannelTypes - mixerProtocol actions is changed from string to Array ([5448e7a](https://github.com/olzzon/sisyfos-audio-controller/commit/5448e7ab273c0ad5f5b11e5f6326c77058e3fb7d)) +- ChannelTypes - preparing settings for numberOfChannelTypes ([ef1a9ba](https://github.com/olzzon/sisyfos-audio-controller/commit/ef1a9baa9f6e98255ab95fec560b70b0dd1c230d)) +- channeltypes- OscMixerConnection send level to the different channelTypes ([fd6d9ef](https://github.com/olzzon/sisyfos-audio-controller/commit/fd6d9ef7f62e40aa9bdd383dad56d4efe3479c41)) +- ChannelTypes: Changed numberOfChannels to numberOfChannelsInType (current ussage is [0]) ([114538d](https://github.com/olzzon/sisyfos-audio-controller/commit/114538d4800b47150e86078dbf8d2e74767d6850)) +- DMXIS - set label from Automation to DMXIS ([ac4038f](https://github.com/olzzon/sisyfos-audio-controller/commit/ac4038f8c831f59eb2fd58f3a730b5d9ccdb8fef)) +- Ember - trying to figure out invokeFunction ([0210ed1](https://github.com/olzzon/sisyfos-audio-controller/commit/0210ed1052c988418e0ce6eeeb35caf6b19c96d6)) +- Ember - trying to figure out setValue (right now it only resets the value) ([1e27c53](https://github.com/olzzon/sisyfos-audio-controller/commit/1e27c53b2a3f637230079d9156c632791226cee6)) +- Ember Protocol - Subscribe label changes ([5b83282](https://github.com/olzzon/sisyfos-audio-controller/commit/5b83282f9d4ae7a30e68f5474ce52d1fedf3bde3)) +- Ember Studer support - Added Vista 1 - Vista 5 - Vista 9 ([d602daa](https://github.com/olzzon/sisyfos-audio-controller/commit/d602daac47c9ff01f656de47cff8986fa1cdc1d2)) +- fader -> channel routing. implementing faders reducer in channel component ([85a1705](https://github.com/olzzon/sisyfos-audio-controller/commit/85a1705bb6f0179ca49120305c06c194edfd8b33)) +- Fader-Channel routing - initial datastructure for abstration of fader - channel ([93af7b1](https://github.com/olzzon/sisyfos-audio-controller/commit/93af7b14404b4d4ee812c4572f7bb89d16969d97)) +- Hui Remote - change of fader from Sisyfos to HUI working. ([c6f07a9](https://github.com/olzzon/sisyfos-audio-controller/commit/c6f07a92425f93cd3347e8f242309c5e820d4210)) +- Hui remote - Remote solo button toggles Sisyfos PFL on/off ([2587ff8](https://github.com/olzzon/sisyfos-audio-controller/commit/2587ff80263e4e842142b790171c61c5638e5d91)) +- hui remote - Select button togles sisyfos PGM on/off ([3ad29b5](https://github.com/olzzon/sisyfos-audio-controller/commit/3ad29b59024a7bf243d50f22837578663e817712)) +- HUI remote - Status of SELECT and SOLO button led updates when button is pressed ([bd40f81](https://github.com/olzzon/sisyfos-audio-controller/commit/bd40f812a0c7ba41b78a98e8e5f965bfac99018a)) +- hui remote - update hui if mixer faders are changed by mixer ([8bb116a](https://github.com/olzzon/sisyfos-audio-controller/commit/8bb116a9a28d0e080e8b7fb1869066f571b9c1e8)) +- HUI-remote - Button led reflects Sisyfos state ([df620b9](https://github.com/olzzon/sisyfos-audio-controller/commit/df620b93e36f136a6332f2efb7c7b80238d2a853)) +- implement aux configuration in Storage load/save ([7e01f2a](https://github.com/olzzon/sisyfos-audio-controller/commit/7e01f2a153a1d2e7e76db9c00f3c067718a62928)) +- Implemented "zero" indicator on Faders ([6ee7029](https://github.com/olzzon/sisyfos-audio-controller/commit/6ee702921f55484f021dcd7330b6caff46f70b10)) +- Initial support for Ardour ([4512985](https://github.com/olzzon/sisyfos-audio-controller/commit/4512985b01af5b8be70fc5a344e668a2ed0b83dd)) +- Lawo R3LAYVRX4 - NOT WORKING YET ([ffccf79](https://github.com/olzzon/sisyfos-audio-controller/commit/ffccf792c37d3d0604205787c3898e2f08abd0ce)) +- Let an automation system ping sisyfos, to verify connectivity status. ([b3a1a46](https://github.com/olzzon/sisyfos-audio-controller/commit/b3a1a4665076958aacc6004c2d35b648d66a1784)) +- Midi Mixer Protocol - settings select Midi input and output port, when a MIDI mixer protocol is selected ([3dd2567](https://github.com/olzzon/sisyfos-audio-controller/commit/3dd2567660e2254bb6ad9a7dddd9dcdc1dd2c194)) +- MidiMixerConnection - using type from protocol ([96576f4](https://github.com/olzzon/sisyfos-audio-controller/commit/96576f4a18dfb1c054e48778be1a06d87839659d)) +- MixerProtocol prepared ChannelType based structure. ([bd05bb5](https://github.com/olzzon/sisyfos-audio-controller/commit/bd05bb5492e10e834a3e2e6560dbae2e6a735fe4)) +- New ChannelType - channelType and channelIndexType implemented in channelReducer and snapShot state ([4082795](https://github.com/olzzon/sisyfos-audio-controller/commit/4082795b834ab71cd0fac940e0b4e5b495840531)) +- new ChannelTypes - settings number of each channeltypes ([b733529](https://github.com/olzzon/sisyfos-audio-controller/commit/b73352959b48bcaed5337b68f2b8fa88261d22e7)) +- Protocol for DMXIS lightcontrol ([0c9cb1f](https://github.com/olzzon/sisyfos-audio-controller/commit/0c9cb1f41ec029535c501a82e5cb3d967852482e)) +- Reaper Master Protocol DCA support ([f301dcd](https://github.com/olzzon/sisyfos-audio-controller/commit/f301dcd05828b82b4f805744dde13f9c1e72a4ad)) +- remote midi connetion - prefare PFL ([ffbde02](https://github.com/olzzon/sisyfos-audio-controller/commit/ffbde02ca822cbca644fc4096333a7a5ed8b8ab3)) +- Remote midi controÃller - update mixer when recieving level change from remote ([ccf95b3](https://github.com/olzzon/sisyfos-audio-controller/commit/ccf95b3b490988e6eff8f600286ac92b85f08ab4)) +- Remote Midi Control - working on datastructure ([b15542f](https://github.com/olzzon/sisyfos-audio-controller/commit/b15542f7ae08b1422fd22576acc8ba78958a2127)) +- Remote midi controller - change generic midi remote contrioller to a dedicated HUI controller ([73e4372](https://github.com/olzzon/sisyfos-audio-controller/commit/73e4372a1bdb0de9204aee41edd0c053df3f61ec)) +- Remote Midi Controller - connect to selected midiports from settings ([1eb4500](https://github.com/olzzon/sisyfos-audio-controller/commit/1eb45001f43579060341120bee29740da48c5423)) +- Remote midi controller - Convert Midi controller levels to audio mixer levels ([ddde5fc](https://github.com/olzzon/sisyfos-audio-controller/commit/ddde5fcd109583caa7b255a8fd6cabd600295945)) +- Remote Midi controller Adding support for play, stop, pitch bend types in remote protocol. instead of just ctrl-change ([f043c97](https://github.com/olzzon/sisyfos-audio-controller/commit/f043c974a1d4cfc6387d926cfbf7a5b4fe847eac)) +- Remote MidiControl - Added Faderlevel ([20a9548](https://github.com/olzzon/sisyfos-audio-controller/commit/20a954834eb05c6f1f401500cae7af805f095f10)) +- Remote MidiController - mixerConnection to be used for updating mixer status ([8f404a5](https://github.com/olzzon/sisyfos-audio-controller/commit/8f404a50f6821d41faeead94e5774ab3bab9d3fa)) +- Remote MidiController - preparing value conversion from mixer min-max to remote min-max ([e4764b9](https://github.com/olzzon/sisyfos-audio-controller/commit/e4764b97a252d5990849a1dc2f6b7b1a13028cb0)) +- Remote midicontroller - Recieve messages working ([d60ad72](https://github.com/olzzon/sisyfos-audio-controller/commit/d60ad72cc2d71354ad1712afbc9a82309d53477c)) +- Remote Midicontroller - Settings added pull down menus for selecting midiports in and out for controller ([6e754cd](https://github.com/olzzon/sisyfos-audio-controller/commit/6e754cd93332413873f43593f739594bfb54789a)) +- remote-hui fader from hui to sisyfos working ([97e6faa](https://github.com/olzzon/sisyfos-audio-controller/commit/97e6faa18d001c588cb7b35f899a3affb2f90794)) +- RemoteFader support - preparing support ([5ed8364](https://github.com/olzzon/sisyfos-audio-controller/commit/5ed83643e250f544cbf8c5323a746d0516ea6b31)) +- Set channel label on mixer from Sisyfos and from Automation ([35fbc34](https://github.com/olzzon/sisyfos-audio-controller/commit/35fbc3485c521d92796bcfe5016b7c3081ad0eae)) +- Studer Vista - initial support ([ea054e3](https://github.com/olzzon/sisyfos-audio-controller/commit/ea054e3c05225b50deb5cb841082de7b168e83ff)) +- Studer Vista Label support ([fbaf105](https://github.com/olzzon/sisyfos-audio-controller/commit/fbaf10514a9ac2f7d72293a83f7ad578566c54cf)) +- support restarting source producer to change source properties ([ad9c560](https://github.com/olzzon/sisyfos-audio-controller/commit/ad9c560eb3fe848c5031caa079a8914ef2ca23a9)) +- Yamaha QL1 midi support - basic funtionality working ([e7460e2](https://github.com/olzzon/sisyfos-audio-controller/commit/e7460e274a921d67ba0c449b53b931aa8873f2dc)) +- Yamaha QL1 support - created protocol (not functioning yet) ([497db09](https://github.com/olzzon/sisyfos-audio-controller/commit/497db09ed654cb661ade12899a25887305ba22a6)) +- **casparcg:** support VU meters on CCG mixer ([f6a5c4d](https://github.com/olzzon/sisyfos-audio-controller/commit/f6a5c4d59a92d5604715a343dc73cdfbb5228a53)) + +### Bug Fixes + +- /state/full should include showFader status ([c0be854](https://github.com/olzzon/sisyfos-audio-controller/commit/c0be854eafbdb6529f895fa214a8aba339d70e75)) +- as new react-slider module has a z-index of 1, settings pages are changed to a z-index of 2 ([af5a46c](https://github.com/olzzon/sisyfos-audio-controller/commit/af5a46c5c83a03b9ece3d11880b9a50e8fe9a5aa)) +- Automation PST command must update NextAux ([f635362](https://github.com/olzzon/sisyfos-audio-controller/commit/f63536225983f1f8c88550c9c7cb637aebf66e23)) +- Automationprotocol - return address data structure is to.address not to.ip ([75ceb9a](https://github.com/olzzon/sisyfos-audio-controller/commit/75ceb9aacdeda699d72108b7a9109ee5b5a24371)) +- CasparCG protocol min and zero values are used in channelTypes, so they are adjusted accoringly ([be6a5eb](https://github.com/olzzon/sisyfos-audio-controller/commit/be6a5eb814dad27f130ee9caf1d80378e0f669b5)) +- channel - fader abstractions was not correct ([5145b43](https://github.com/olzzon/sisyfos-audio-controller/commit/5145b43d69bd16ad86ab78977d21b0d1ad97b457)) +- Channel had faderChannel as reference instead of ch ([ea877dd](https://github.com/olzzon/sisyfos-audio-controller/commit/ea877dd495bf8c1f9e7b9b0fb9fd5db04fcb146b)) +- checkOscCommand - returned always true ([d502820](https://github.com/olzzon/sisyfos-audio-controller/commit/d50282082340bd53ca82386f8115c8f97038a332)) +- ClassNames in Sttings was there by accident ([c6d29b6](https://github.com/olzzon/sisyfos-audio-controller/commit/c6d29b6c01a77cded8507b232ab78c29842c51f4)) +- Clear protocolDelay timer when aborting old fade ([7801638](https://github.com/olzzon/sisyfos-audio-controller/commit/78016382f7430d723c59128f17dde6257e4562cb)) +- Colors for active faders was missing after converting to react-slider based faders ([15e34f3](https://github.com/olzzon/sisyfos-audio-controller/commit/15e34f3202e6356b5489261f96747a9363b6105a)) +- don´t send faderLeel to mixer, as it reference to multiple channels now. ([a2a1240](https://github.com/olzzon/sisyfos-audio-controller/commit/a2a124037099c83a1b88acf0afff8d6aa8b09a48)) +- Electron nodeIntegration: false - added preload.js - prepare for moving hw related stuff to server side ([2ec903d](https://github.com/olzzon/sisyfos-audio-controller/commit/2ec903d56c133c963a412b8683b1641fd8d99eae)) +- Fade I/O - use channelType min and zero for setting target gain ([6a935c6](https://github.com/olzzon/sisyfos-audio-controller/commit/6a935c6e58344bbe0c473bcb451d1bf7bcf32a65)) +- fadeToBlack - only send commands for channels that are open ([48ed2ae](https://github.com/olzzon/sisyfos-audio-controller/commit/48ed2aef0792fe506fad401ccc8b8f531df4aa88)) +- ipaddress of return message is not to.id but to.address ([b5f3871](https://github.com/olzzon/sisyfos-audio-controller/commit/b5f387167cfb7ea8c61b34b7575ca77d8e4b1f04)) +- Meter align with "zero" ([48f662a](https://github.com/olzzon/sisyfos-audio-controller/commit/48f662a80f7f474c5f27ae82c2e595d356985ae0)) +- Midi - addListener should have channel number and not controlchange number ([aec6ea8](https://github.com/olzzon/sisyfos-audio-controller/commit/aec6ea8b8f030cd2310449e982c23ac1302f4668)) +- Midi HUI remote controller, update new structure fader instead of channel ([c4c9c3b](https://github.com/olzzon/sisyfos-audio-controller/commit/c4c9c3be98915d7a6c2f05afa8e8cfb472445cd5)) +- Midi protocol - update faders when multiple faders are changed ([a8c6da8](https://github.com/olzzon/sisyfos-audio-controller/commit/a8c6da8b121f405ca76633f8facf68f77da7e886)) +- More fader steps in Yamaha QlCl protocol (before it only had 10 steps from 0 to 1) ([a9d81a8](https://github.com/olzzon/sisyfos-audio-controller/commit/a9d81a8ac1ce7b9d20d674bd4da1786236fb9bca)) +- new channelType - emberMixerConnection, subscription used ch instead og channelTypeIndex ([0d630bb](https://github.com/olzzon/sisyfos-audio-controller/commit/0d630bb9bd70b5ef2a27f1a8e1d58469fc1d8a1e)) +- new forked osc.js dependcy, to allow use without rebuilding ([bf8797b](https://github.com/olzzon/sisyfos-audio-controller/commit/bf8797bafdfa6193154b290eb4aeaf17e25cd9fb)) +- numberOfChannels pr. type instead of totalNumberOfChannels ([139b4c1](https://github.com/olzzon/sisyfos-audio-controller/commit/139b4c1a296cea71b3e0565b6c9c80af661f5f2a)) +- only channels of first channelttype was set after reload ([f50296e](https://github.com/olzzon/sisyfos-audio-controller/commit/f50296e57773a8020d63699ee0fad24f8aa27ef8)) +- OSC command had wrong fader Index ([bef73e4](https://github.com/olzzon/sisyfos-audio-controller/commit/bef73e4af204b3cfa86919e13a0300e4bf8766be)) +- OSC protocol - All faders follows when changed on mixer ([b5d9515](https://github.com/olzzon/sisyfos-audio-controller/commit/b5d9515601d55bc963f672360fda6381704a6642)) +- Package.json --asar does not take any arguments ([dcfa901](https://github.com/olzzon/sisyfos-audio-controller/commit/dcfa9011b8926766e6e96f950a101795447bb62b)) +- pass auxIndex to aux level reducer ([a41b987](https://github.com/olzzon/sisyfos-audio-controller/commit/a41b9878e87a1c044548aea049c880be3cdda819)) +- PFL should not mute channel ([3c66960](https://github.com/olzzon/sisyfos-audio-controller/commit/3c669601c848230bd086afcdbe36c1746c297779)) +- pgm off didn´t get a prober fadetime ([1cbf98b](https://github.com/olzzon/sisyfos-audio-controller/commit/1cbf98b4b5cd9b8f77011b11248cf6112c10891f)) +- problem with CCG interface incorrectly understanding decklink device ID ([8889acd](https://github.com/olzzon/sisyfos-audio-controller/commit/8889acd6493f2bd0a37933168ba3ab8a72a74564)) +- QlClMixerConnection bug re huiRemoteConnection ([892bc27](https://github.com/olzzon/sisyfos-audio-controller/commit/892bc27a97956b35def27bb008e250e67df8db94)) +- QlClMixerConnection called hui with wrong argument ([8fbdd1b](https://github.com/olzzon/sisyfos-audio-controller/commit/8fbdd1b3635c8d0f40debb4c2dbd2b73c834fa88)) +- Reaper protocol. Wrong handling of feedback from mixer ([51bd2fb](https://github.com/olzzon/sisyfos-audio-controller/commit/51bd2fb638715670066a17275b17ca3e424cadc7)) +- send state commands back to right ip and expose full state ([3a6f257](https://github.com/olzzon/sisyfos-audio-controller/commit/3a6f257de1de1557e802e2572c4c4bbd64e48b3e)) +- setting menu, added cancel button to reload without saving ([931ddbe](https://github.com/olzzon/sisyfos-audio-controller/commit/931ddbefbe89d42bb3226f2ad913917f9aa77d55)) +- settings - Protocol specific options displayed when protocol is changed (e.g. midi ports when a MIDI based protocol is selected) ([25167d2](https://github.com/olzzon/sisyfos-audio-controller/commit/25167d2bf0cd8a65477eeec2d937e62e5d4c8202)) +- settings and routing menus position: fixed instead of absolute ([591877e](https://github.com/olzzon/sisyfos-audio-controller/commit/591877e73338e36be2c4c957dd0a79b13a2040f3)) +- showMessageBoxSync parsed a null to an optional argument. Now removed ([3f4561f](https://github.com/olzzon/sisyfos-audio-controller/commit/3f4561febd6c1157d0980d3e177445296798e3c1)) +- slider scroll - check for touchscreen ([7331216](https://github.com/olzzon/sisyfos-audio-controller/commit/73312166258c3afd8b4249cc11957bb1968a302b)) +- SSL adjust fader all way to zero ([894a406](https://github.com/olzzon/sisyfos-audio-controller/commit/894a4065894c6b49136294d5b9d999f38b3474f6)) +- SSL check for negative value before converting to Uint8Array ([54edfa3](https://github.com/olzzon/sisyfos-audio-controller/commit/54edfa33c1f6e2697aad15993c073c1bd3bc7192)) +- SSL protocol did not receive initial state from desk. ([9009d46](https://github.com/olzzon/sisyfos-audio-controller/commit/9009d46314c4da6acbe96308b2d3a2e81815a50d)) +- StuderVistaEmber file added ([bc4dcb3](https://github.com/olzzon/sisyfos-audio-controller/commit/bc4dcb39aa863577dbc7db05cf4d45aac33335af)) +- toggleShowChannelStrip toggle between channels ([22abc5f](https://github.com/olzzon/sisyfos-audio-controller/commit/22abc5faaa51cac5adc6be378ab05f3b8c61d607)) +- typeof declarationas ([d627950](https://github.com/olzzon/sisyfos-audio-controller/commit/d62795067bd29d7af98602291ff035569e19eda0)) +- undo emptMiserMessage() as it didnt work inside object ([5da0bea](https://github.com/olzzon/sisyfos-audio-controller/commit/5da0bea9433e78e0f909f37ae5bb4b6296d1832f)) +- update HUI remote fader, when level are changed from the mixer ([b762d5f](https://github.com/olzzon/sisyfos-audio-controller/commit/b762d5f6c9c3e85409be17fd0b580d76322a6b06)) +- upload preload.js file after it was moved ([b87c859](https://github.com/olzzon/sisyfos-audio-controller/commit/b87c859525ee22c7215857e829786dd10b2d6d47)) +- Webpack build - removed Babili and css mini extract plugins ([8ebd664](https://github.com/olzzon/sisyfos-audio-controller/commit/8ebd6649503c6626129c7c362545e06080fe64b3)) +- when receiving fader update from mixer, responded level should be faderlevel not outgain ([0fd1bd5](https://github.com/olzzon/sisyfos-audio-controller/commit/0fd1bd53b0291ab7546c1cb228d52c5f9d339783)) +- z-index was added to settings.css (as module react-slider has a z-index=1) ([b666157](https://github.com/olzzon/sisyfos-audio-controller/commit/b666157b68479dba46a74dcf9cd8de2082fb1d9c)) +- **casparCG:** ensure that the filePath is a string ([248f863](https://github.com/olzzon/sisyfos-audio-controller/commit/248f86374a2b4aafef5cd41f7dc3291f00b3322e)) +- **casparcg:** resolve an issue with PFL ([caf4946](https://github.com/olzzon/sisyfos-audio-controller/commit/caf494634876fc51ce895a377f2d8a735b3c3641)) +- added file for last commit ([6197f2b](https://github.com/olzzon/sisyfos-audio-controller/commit/6197f2b35113ae9b8886f1a27ff04a2e1131fcee)) +- added midiReceiveType variable ([abc1c2a](https://github.com/olzzon/sisyfos-audio-controller/commit/abc1c2a0ec00fa0476ac744f877a063614d2ff28)) +- adding .ts files for last commit ([85cb336](https://github.com/olzzon/sisyfos-audio-controller/commit/85cb33641578aae5a8f3d5c523b4816ba2df2ee4)) +- App -> passed an unused argument to MidiRemoteConnection ([386d496](https://github.com/olzzon/sisyfos-audio-controller/commit/386d4967c42cf8146c3bea1b267050192f6a2e16)) +- AutomationConnection, OSC server could only receive local connections. IP changed to 0.0.0.0 ([ceb4d2f](https://github.com/olzzon/sisyfos-audio-controller/commit/ceb4d2f523f1173941d1172c6a847ab49a7e0031)) +- Background on the whole mixer should be black ([e3e1583](https://github.com/olzzon/sisyfos-audio-controller/commit/e3e1583577e7cfbd9e7a4c16ac73e3961b212706)) +- behringer and midas vu-meter import was removed ([d557479](https://github.com/olzzon/sisyfos-audio-controller/commit/d55747927f75e1c687d8be8634629a2b7471a68d)) +- bouldn´ build app. Babel didn´t have preset-env installed ([58c573b](https://github.com/olzzon/sisyfos-audio-controller/commit/58c573b224d96f6c4b18451d63fbd6bba20768f5)) +- changed value var to any as it can be a string or a number ([cb975a9](https://github.com/olzzon/sisyfos-audio-controller/commit/cb975a9dbbbe6d7328076a45b0b456bf179effe5)) +- check for placement of {channel} in OSC commands ([67bab5b](https://github.com/olzzon/sisyfos-audio-controller/commit/67bab5b63316c4e93ed810a6665dadd2befd8a19)) +- checkOSC command, if {channel} was last parameter in command it returned false ([c959bf0](https://github.com/olzzon/sisyfos-audio-controller/commit/c959bf0d3337357bab0f14b5e6dedde593529e79)) +- CI added environment in test ([11ce0ee](https://github.com/olzzon/sisyfos-audio-controller/commit/11ce0ee8680600164ad08856c6b2ce9560263f23)) +- CI comment out whole test ([f3eb9f2](https://github.com/olzzon/sisyfos-audio-controller/commit/f3eb9f26a84ae0da465cfc12e6c5b48c29c47391)) +- CI only test build ([7905a6b](https://github.com/olzzon/sisyfos-audio-controller/commit/7905a6bccd13bd72b3ccb53621484a8472a56371)) +- CI only test build ([0c178b5](https://github.com/olzzon/sisyfos-audio-controller/commit/0c178b5fe5f91da24a420d92dd34b02416cbf8a5)) +- defaultChannelReducerState pushed to undefined array. ([f829191](https://github.com/olzzon/sisyfos-audio-controller/commit/f8291913aae5f156f2608632d5096654279a1419)) +- enable/disable HuiRemoteController in settings ([39e0824](https://github.com/olzzon/sisyfos-audio-controller/commit/39e08249152790a1ba4b1635acdf9775c36db29a)) +- Fade to excact target val (and not nearby) ([feafa5e](https://github.com/olzzon/sisyfos-audio-controller/commit/feafa5eacba96008f755199f1f719c187ed70882)) +- fadeOut didn´t end if fader was exactly === min ([2868a62](https://github.com/olzzon/sisyfos-audio-controller/commit/2868a629f7df645e0953440b81353cb0b9e8f7ca)) +- Fadi In/out when "master" mode didn´t turn down when PGM was on. ([2313f0d](https://github.com/olzzon/sisyfos-audio-controller/commit/2313f0d12bd9ca5628ce4567afab41a684babd33)) +- forgot to add new files in new location on last commit. ([b6e24ab](https://github.com/olzzon/sisyfos-audio-controller/commit/b6e24abf4a873023cd1ff03ea1270cefc7c529e4)) +- GrpFader.css - grpFader-pst-button.on show inactive color and off show active ([f8b3dc9](https://github.com/olzzon/sisyfos-audio-controller/commit/f8b3dc9a3e5bd8a9f66747c0654094fc090fc9a1)) +- GrpFader.tsx should not be a PurComponent when using shouldCompenentUpdate ([77ca0e3](https://github.com/olzzon/sisyfos-audio-controller/commit/77ca0e3ed9afa44e5692dbc380bfa566ecba30ce)) +- HUI remote - change test order of midi message so it checks for fader change before test for button ([38a71f7](https://github.com/olzzon/sisyfos-audio-controller/commit/38a71f7ea357b0355eae79c06434bf607a4f39b8)) +- HUI remote - only update HUI if connected ([ed855c0](https://github.com/olzzon/sisyfos-audio-controller/commit/ed855c0510885a2bf47b76177377bd8c2feea4f8)) +- Index offset when calling snap from automation ([28906d2](https://github.com/olzzon/sisyfos-audio-controller/commit/28906d273ce143b9a48f200401ded7d375f2b472)) +- Individual fadetime, use fadeTime var instead of default value in Fades ([dbf1f9b](https://github.com/olzzon/sisyfos-audio-controller/commit/dbf1f9bd81b00cd2e819dc7047288a1693f8fc09)) +- linux and win builds, no icon ([512b361](https://github.com/olzzon/sisyfos-audio-controller/commit/512b361e2894ce2193170086a5014eb9f57b126c)) +- Meters didn´t work on behringer and midas after renaming. ([b090182](https://github.com/olzzon/sisyfos-audio-controller/commit/b0901829b08f59d3466cceddfe75d85419c3e6e5)) +- missing /ch/1/visible ([f16674a](https://github.com/olzzon/sisyfos-audio-controller/commit/f16674ac4245313a1fb0d577f31ef3ac7e810ec8)) +- MixerConnection - Fade dispatch resolution didn´t iterate ([4cf207f](https://github.com/olzzon/sisyfos-audio-controller/commit/4cf207f70d7f108e82829620eebfcc6bd57dfcbc)) +- moved channelTypes to IMixerProtocolGeneric as it´s need when initialising the App for total number of channels ([33400f3](https://github.com/olzzon/sisyfos-audio-controller/commit/33400f36899e95ab9d5f96dbc43f49269f2be369)) +- offset between channel and array ([8e0fe91](https://github.com/olzzon/sisyfos-audio-controller/commit/8e0fe91e2b0d2f10713795ba0ea98743651717e8)) +- Only rerender when new state in store. Bug: snapOn is an array and forces a re-render everytime the redux runs it´s reducer ([98e48a1](https://github.com/olzzon/sisyfos-audio-controller/commit/98e48a164eadb878127a8b1e1574ddae416125b9)) +- PFL pass complete OSC command for turning on and of PFL ([acb3108](https://github.com/olzzon/sisyfos-audio-controller/commit/acb3108c89ca713ff55d92b8bca33d0f716f80e8)) +- Protocol cleanup - removed references to deleted protocols ([d01d3ca](https://github.com/olzzon/sisyfos-audio-controller/commit/d01d3ca792b5a6cf5f88c8a2ea7f1141fa2d941f)) +- Protocol cleanup, removed protocols deleted in import ([9afeded](https://github.com/olzzon/sisyfos-audio-controller/commit/9afeded2e30a03326d2b73c96a8344a09887c8d2)) +- re-render grp fader ([738895c](https://github.com/olzzon/sisyfos-audio-controller/commit/738895c6077dbe821126a947d427316348e9b411)) +- refered to props store instead of windows store ([f022d79](https://github.com/olzzon/sisyfos-audio-controller/commit/f022d79cac9b9e3b7a0c1406ae424328335f2c0a)) +- removed double background-color assignment in Channel.css ([9213f50](https://github.com/olzzon/sisyfos-audio-controller/commit/9213f50a9527e4dd9097f53311e3b9ce5b65c2e3)) +- Rerender when clicking on a snap button. props state is now each elements value and not the object of the element ([fbe8dcd](https://github.com/olzzon/sisyfos-audio-controller/commit/fbe8dcd837b81523e74093443aec4c955b9173c3)) +- SET_OUTPUT_LEVEL didn´t have a return so VU was set. ([0d14869](https://github.com/olzzon/sisyfos-audio-controller/commit/0d14869bd7ffea5541c2abc09ed0548714fd22e6)) +- slow crossfade when take 32channels. dispatchTrigger added, so store only updates every 5 times the OSC fader is updated. ([f70061d](https://github.com/olzzon/sisyfos-audio-controller/commit/f70061dc8052675121abefe3f6c2ee0f60dce7ef)) +- small type fixes ([d6d673f](https://github.com/olzzon/sisyfos-audio-controller/commit/d6d673ff208ee9a5ef2a428c1a1da16623bc3c58)) +- toggling a snap on a channel didn´t update the gui. its now checked in shouldComponentUpdate ([face0e3](https://github.com/olzzon/sisyfos-audio-controller/commit/face0e3288f1028031041112d242191b4ebbaa4c)) +- turned on channel instead of GrpFader ([56868af](https://github.com/olzzon/sisyfos-audio-controller/commit/56868af2840a6e7c19cf95c7fedc6104f4ddced8)) +- type - assigned true to pflOn instead of comparing in if ( = instead of === ) ([83e0cba](https://github.com/olzzon/sisyfos-audio-controller/commit/83e0cbac1e4c950777e28468a579b8ea8a77485f)) +- type used = instead of === ([c350927](https://github.com/olzzon/sisyfos-audio-controller/commit/c35092755abbde9ea6e586ca67b42bca9860417e)) +- TYPO ([e2f761a](https://github.com/olzzon/sisyfos-audio-controller/commit/e2f761a9db7e9b1bb1224f6ab5e41db949987133)) +- Update gain level in redux store so a change of volume while fading doesn´t jump back to gain from before last fade start ([68ae069](https://github.com/olzzon/sisyfos-audio-controller/commit/68ae0698bfd9c817286dfd158f4be8d5ecf4f87a)) +- Update webpack.build for ts with babel. ([70e2437](https://github.com/olzzon/sisyfos-audio-controller/commit/70e2437d870f699e03e79191119de4e4e6314a3c)) +- When an channelsetting is on and new protocol are selected that haven´t implementee channelsettings, the settings wouldn´t go away after reload. ([82373dd](https://github.com/olzzon/sisyfos-audio-controller/commit/82373dd0600e2fc21438f59af4b5461264dd048e)) +- When running as "master" volume did not lower when pgm on. ([069b4b0](https://github.com/olzzon/sisyfos-audio-controller/commit/069b4b0ab7cf81ffb73618b2a1bdd26830b28057)) +- window size on open, element types in Settings ([cdb2430](https://github.com/olzzon/sisyfos-audio-controller/commit/cdb2430b018db720f829c8c702dcdb5e1c07cbb6)) +- yarn build - did not build as || was used instead of && ([48930e8](https://github.com/olzzon/sisyfos-audio-controller/commit/48930e8d64bea302d8bdf40413faed675c3bbeb6)) diff --git a/Dockerfile b/Dockerfile index 0943d8c3..3055802f 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,19 @@ -FROM node:12.13.1-alpine -COPY . /opt/sisyfos-audio-controller +# BUILD IMAGE +FROM node:16.14-alpine +RUN apk add --no-cache git WORKDIR /opt/sisyfos-audio-controller -EXPOSE 1176/tcp +COPY . . +RUN yarn --check-files --frozen-lockfile +RUN yarn build +RUN yarn --check-files --frozen-lockfile --production --force +RUN yarn cache clean + +# DEPLOY IMAGE +FROM node:16.14-alpine +WORKDIR /opt/sisyfos-audio-controller +COPY --from=0 /opt/sisyfos-audio-controller . +EXPOSE 1176/tcp EXPOSE 1176/udp EXPOSE 5255/tcp EXPOSE 5255/udp -CMD ["yarn", "start"] \ No newline at end of file +CMD ["yarn", "start"] diff --git a/Dockerfile.circle b/Dockerfile.circle new file mode 100644 index 00000000..d4cc1e8a --- /dev/null +++ b/Dockerfile.circle @@ -0,0 +1,5 @@ +FROM node:12.16.0-alpine +RUN apk add --no-cache tzdata +COPY . /opt/sisyfos-audio-controller +WORKDIR /opt/sisyfos-audio-controller +CMD ["yarn", "start"] diff --git a/Docs/CasparCG-Example/sisyfos-casparcg-geometry.json b/Docs/CasparCG-Example/sisyfos-casparcg-geometry.json index 726699fa..d947b303 100644 --- a/Docs/CasparCG-Example/sisyfos-casparcg-geometry.json +++ b/Docs/CasparCG-Example/sisyfos-casparcg-geometry.json @@ -1,86 +1,86 @@ -{ - "label": "Sofie CasparCG Example", - "fromMixer": { - "CHANNEL_VU": [ - ["/channel/1/stage/layer/51/audio/1/pFS", "/channel/1/stage/layer/51/audio/2/pFS"], - ["/channel/1/stage/layer/52/audio/1/pFS", "/channel/1/stage/layer/52/audio/2/pFS"], - ["/channel/1/stage/layer/53/audio/1/pFS", "/channel/1/stage/layer/53/audio/2/pFS"], - ["/channel/1/stage/layer/54/audio/1/pFS", "/channel/1/stage/layer/54/audio/2/pFS"], - ["/channel/1/stage/layer/55/audio/1/pFS", "/channel/1/stage/layer/55/audio/2/pFS"], - ["/channel/1/stage/layer/56/audio/1/pFS", "/channel/1/stage/layer/56/audio/2/pFS"] - ] - }, - "toMixer": { - "MONITOR_CHANNEL_FADER_LEVEL": [ - [ - { "channel": 2, "layer": 51 } - ], - [ - { "channel": 2, "layer": 52 } - ], - [ - { "channel": 2, "layer": 53 } - ], - [ - { "channel": 2, "layer": 54 } - ], - [ - { "channel": 2, "layer": 55 } - ], - [ - { "channel": 2, "layer": 56 } - ] - ], - "PGM_CHANNEL_FADER_LEVEL": [ - [ - { "channel": 1, "layer": 51 }, - { "channel": 3, "layer": 51 } - ], - [ - { "channel": 1, "layer": 52 }, - { "channel": 3, "layer": 52 } - ], - [ - { "channel": 1, "layer": 53 }, - { "channel": 3, "layer": 53 } - ], - [ - { "channel": 1, "layer": 54 }, - { "channel": 3, "layer": 54 } - ], - [ - { "channel": 1, "layer": 55 }, - { "channel": 3, "layer": 55 } - ], - [ - { "channel": 1, "layer": 56 }, - { "channel": 3, "layer": 56 } - ] - ] - }, - "channelLabels": [ - "RM1", - "RM2", - "RM3", - "RM4", - "RM5", - "MP1" - ], - "sourceOptions": { - "sources": [ - { "channel": 2, "layer": 51 }, - { "channel": 2, "layer": 52 }, - { "channel": 2, "layer": 53 }, - { "channel": 2, "layer": 54 }, - { "channel": 2, "layer": 55 }, - { "channel": 2, "layer": 56 } - ], - "options": { - "CHANNEL_LAYOUT": { - "1L-2R": "8ch2", - "1L-1R": "4ch-dleft", - "2L-2R": "4ch-dright" - } - } - } -} +{ + "label": "Sofie CasparCG Example", + "fromMixer": { + "CHANNEL_VU": [ + ["/channel/1/stage/layer/51/audio/1/pFS", "/channel/1/stage/layer/51/audio/2/pFS"], + ["/channel/1/stage/layer/52/audio/1/pFS", "/channel/1/stage/layer/52/audio/2/pFS"], + ["/channel/1/stage/layer/53/audio/1/pFS", "/channel/1/stage/layer/53/audio/2/pFS"], + ["/channel/1/stage/layer/54/audio/1/pFS", "/channel/1/stage/layer/54/audio/2/pFS"], + ["/channel/1/stage/layer/55/audio/1/pFS", "/channel/1/stage/layer/55/audio/2/pFS"], + ["/channel/1/stage/layer/56/audio/1/pFS", "/channel/1/stage/layer/56/audio/2/pFS"] + ] + }, + "toMixer": { + "PFL_AUX_FADER_LEVEL": [ + [ + { "channel": 2, "layer": 51 } + ], + [ + { "channel": 2, "layer": 52 } + ], + [ + { "channel": 2, "layer": 53 } + ], + [ + { "channel": 2, "layer": 54 } + ], + [ + { "channel": 2, "layer": 55 } + ], + [ + { "channel": 2, "layer": 56 } + ] + ], + "PGM_CHANNEL_FADER_LEVEL": [ + [ + { "channel": 1, "layer": 51 }, + { "channel": 3, "layer": 51 } + ], + [ + { "channel": 1, "layer": 52 }, + { "channel": 3, "layer": 52 } + ], + [ + { "channel": 1, "layer": 53 }, + { "channel": 3, "layer": 53 } + ], + [ + { "channel": 1, "layer": 54 }, + { "channel": 3, "layer": 54 } + ], + [ + { "channel": 1, "layer": 55 }, + { "channel": 3, "layer": 55 } + ], + [ + { "channel": 1, "layer": 56 }, + { "channel": 3, "layer": 56 } + ] + ] + }, + "channelLabels": [ + "RM1", + "RM2", + "RM3", + "RM4", + "RM5", + "MP1" + ], + "sourceOptions": { + "sources": [ + { "channel": 2, "layer": 51 }, + { "channel": 2, "layer": 52 }, + { "channel": 2, "layer": 53 }, + { "channel": 2, "layer": 54 }, + { "channel": 2, "layer": 55 }, + { "channel": 2, "layer": 56 } + ], + "options": { + "CHANNEL_LAYOUT": { + "1L-2R": "8ch2", + "1L-1R": "4ch-dleft", + "2L-2R": "4ch-dright" + } + } + } +} diff --git a/Docs/pix/AdvancedChannelStrip.png b/Docs/pix/AdvancedChannelStrip.png new file mode 100644 index 00000000..87c23865 Binary files /dev/null and b/Docs/pix/AdvancedChannelStrip.png differ diff --git a/Docs/pix/mic-tally-view.png b/Docs/pix/mic-tally-view.png new file mode 100644 index 00000000..8bf65d3a Binary files /dev/null and b/Docs/pix/mic-tally-view.png differ diff --git a/Docs/pix/minimonitorview.png b/Docs/pix/minimonitorview.png new file mode 100644 index 00000000..ccb5a05f Binary files /dev/null and b/Docs/pix/minimonitorview.png differ diff --git a/README.md b/README.md index dc2b6a4a..29f95c85 100644 --- a/README.md +++ b/README.md @@ -1,170 +1,291 @@ -# Sisyfos Audio Controller - -## Audiomixer control build for intelligent automation. - -You use the fader for the level, and PGM on/off for fade-in/out. -TAKE NEXT crossfades from NEXT to PGM - -It´s fast to see what faders are on-aie, and whether they are PGM level or Voiceover level - -### GUI with open channelstrip: - - -### These are the functions on each channel: - - -### These are the functions on the channelstrip: -(You open the channelstrip by clicking on the channel label) - - - - - - -### Routing of Faders to Channels -Routing of Faders to multiple channels or a single channel are possible. This way Sisyfos can control some or all channels on a mixer. And a single fader can be used for E.G. a 5.1 (on 6 mono faders) - -### Load/Save Routing -Routing setups can be stored in STORAGE. So it´s possible to have different Routings dependent of what setup the Audio mixer is using. - -### Run as Docker: (On linux) -``` -docker pull olzzon/sisyfos-audio-controller:develop -docker volume create sisyfos-vol -sudo docker run --mount source=sisyfos-vol,target=/opt/sisyfos-audio-controller/storage -e loggerIp='0.0.0.0' -e loggerPort=9300 -e loggerFileLevel='error' --network="host" --restart always olzzon/sisyfos-audio-controller:develop -``` -Running Docker with Elastic Search: -Set env vars: loggerIp=xx.xx.xx.xx and loggerPort=xxxx and loggerLevel='info' - -if you wish to log to logfile instead of kibana: -Set env var: -e loggerFileLevel='info' -(no kibana args will default to: 0.0.0.0:9200 logger level='info') - -### Install Local node host: -(Be aware that a server reload will quit server and you need an external source to restart) -``` -git clone https://github.com/olzzon/sisyfos-audio-controller.git -cd sisyfos-audio-controller -yarn -yarn build -yarn start --loggerConsoleLevel='info' -``` -Running Server with Elastic Search: -(no args will default to: 0.0.0.0:9200) -``` -yarn start --loggerIp '192.168.12.12' --loggerPort 9302 -``` - -### Logger levels: -When running Sisyfos you can define the log level by: -loggerLevel (Kibana log level) and loggerFileLevel (local log file level) and loggerConsoleLevel (local log to console) -The levels are: -* error (only error) -* info (standard info regarding connectiviy and data from Automation protocol etc.) -* verbose (info level plus: data send and received from Audiomixer) - -### Open GUI in browser: -``` -localhost:1176 (or whatever ip you use for Sisyfos Nodejs/Docker) -IF you wan´t to disable settings: -localhost:1176/?settings=0 -``` - -## Settings: -### Show PFL Controls: -As NEXT has been implemented, and PFL usually only work on on channel at a time, the PFL is only working correctly on 1:1 routed setups (And with the CasparCG protocol) - - -(Mixer presets are stored in MixerProtocolPresets.js) -### Following preset name are possible: -* CasparCG - * use storage/default-casparcg.ccg as template and place you own file in storage folder. - * base your casparcg.config by the casparcg.config file in the same folder - * remember to active OSC in the casparcg.config file to it points to Sisyfos - -* reaper - * OSC protocol for control Reaper (reaper.fm) -* Ardour Master - * OSC protocol for Ardour (www.ardour.org) - * Port 3819 - * The volume change in Ardour is on it´s channel faders. - * Todo: - * Group support - * Meter calibration -* SSL System T - Broadcast Mixer - * SSL Automation Protocol for System T - * Port 10001 - * Set Protocol Latency to around 120ms -* Midas Master - * OSC protocol for Midas M32 and Behringer X32 - * Port 10023 -* Behringer xr master - * OSC protocol for Behringer XR12,16,18 - * Port 10024 - * In this version the Behringer is slave of Producers-Audio-mixer, so faders on the behringer is turned down when channel is of. -* DMXIS - Sisyfos control of DMX Lightcontroller - * Default Port is 8000 - * Controls Fader On/Off with preset level from Sisyfos. - * Easy implementation of state based lightcontrol from Automation. - * the PROTOCOL DELAY setting should be raised to 50ms, as DMXIS is responding a little slowly. -* midi - * Generic MIDI - still preminilary - * When using MIDI protocols, the PROTOCOL DELAY setting should be rised to at least 50ms -* Yamaha QL1 - * Ip - MIDI based Protocol - * Port 50000 - * Stable implementation of 2-ways Fader and Mute - - -## Automation Support: -It´s possible to control the Producers-Audio-Mixer from an automationsystem, for it to act as middleware. - -## Set state: -To set the state send these OSC commands from you Automation to ProducersAudioMixer Port: 5255: -#### Set channel to PGM (optional: indiviaul fadetime): -(the integer defines: 0 - Off, 1 - Pgm On, 2 - Voice Over) -(if second is missing it will take default fade value) -/ch/1/mix/pgm - integer: { 0, 1 or 2 } - float { fadetime in ms } -#### Set channel to PST: -/ch/1/mix/pst - integer: { 0, 1 or 2 } (the integer defines: 0 - Off, 1 - Pgm On, 2 - Voice Over) -#### Mute channel: -/ch/1/mute - integer: { 0, 1 } (the integer defines: 0 - Mute off, 1 - Mute On) -#### Set channel faderlevel: -/ch/1/mix/faderlevel - float {between 0 and 1} -#### Set channel label: -/ch/1/label - string {name of channel} -#### Inject Command: -Pass a command directly from Automation to Audiomixer -/inject -#### Crossfade between PGM and PST: -/take -#### Set snap 1-xx to PST: -/snap/1 -#### Fade all channels to black (mute) -/fadetoblack -#### Clear all pst buttons -/clearpst -#### Hide or show channel strips on GUI: -/ch/{value1}/visible - integer { 0 or 1 } - -## Get state: -#### Get full state of all channels: -/state/full - returns a json string with an array of channels: { pgmOn: boolean, pstOn: boolean, faderLevel: boolean } -#### Get state channel PGM: -/state/ch/1/mix/pgm - returns pgm state integer { 0 or 1 } -#### get state channel PST: -/state/ch/1/mix/pst - returns pgm state integer { 0 or 1 } -#### Get state channel faderlevel: -/state/ch/1/mix/faderlevel - float {between 0 and 1} -#### get state channel Mute: -/state/ch/1/mute - returns mute state integer { 0 or 1 } -#### Get state group PGM: -/state/ch/1/mix/pgm - returns pgm state integer { 0 or 1 } -#### get state group PST: -/state/ch/1/mix/pst - returns pgm state integer { 0 or 1 } -#### Get state group faderlevel: -/state/ch/1/mix/faderlevel - float {between 0 and 1} - -## Check connectivity -/ping/{value} -_In response to a ping, sisyfos will reply with /pong and the provided value OR 'offline' if Audiomixer is not connected_ +# Sisyfos Audio Controller + +[![Node CI](https://github.com/tv2/sisyfos-audio-controller/actions/workflows/deploy-image.yml/badge.svg)](https://github.com/tv2/sisyfos-audio-controller/actions/workflows/deploy-image.yml) + +## Audiomixer control build for intelligent automation. + +You use the fader for the level, and PGM on/off for fade-in/out. +TAKE NEXT crossfades from NEXT to PGM + +It´s fast to see what faders are on-aie, and whether they are PGM level or Voiceover level + +### GUI with open channelstrip: + + + +### These are the functions on each channel: + + + +### These are the functions on the channelstrip: + +(You open the channelstrip by clicking on the channel label) +The features on the channelstrip depends on the Mixer Protocol. + + + +### Full Channelstrip: + +(You open the channelstrip by clicking on the "Full Ch.Strip" in the normal channelstrip) + +The Advanced channelstrip has all the features the seleced Mixer Protol supports. (Example: Midas M32) + + + +### If you need a MiniMonitorView for a client: + +Run webpage with + +``` +localhost/?view=minimonitor +``` + + + +### If you need a Microphone Tally View for a client: + +Run webpage with + +``` +localhost/?view=mic-tally +``` + +Microphone Tally View + +### Routing of Faders to Channels + +Routing of Faders to multiple channels or a single channel are possible. This way Sisyfos can control some or all channels on a mixer. And a single fader can be used for E.G. a 5.1 (on 6 mono faders) + +### Load/Save Routing + +Routing setups can be stored in STORAGE. So it´s possible to have different Routings dependent of what setup the Audio mixer is using. + +### Run as Docker: (On linux) + +``` +docker pull tv2media/sisyfos-audio-controller:develop +docker volume create sisyfos-vol +sudo docker run --mount source=sisyfos-vol,target=/opt/sisyfos-audio-controller/storage --network="host" --restart always tv2media/sisyfos-audio-controller:develop +``` + +### Run as Docker: (On windows) + +``` +docker pull tv2media/sisyfos-audio-controller:develop +docker volume create sisyfos-vol +docker run --mount source=sisyfos-vol,target=/opt/sisyfos-audio-controller/storage -p 1176:1176 -p 5255:5255 --restart always tv2media/sisyfos-audio-controller:develop +``` + +### Install Local node host: + +(Be aware that a server reload will quit server and you need an external source to restart) + +``` +git clone https://github.com/tv2media/sisyfos-audio-controller.git +cd sisyfos-audio-controller +yarn +yarn build +yarn start +``` + +### Log levels: + +When running Sisyfos you can define the log level by setting the environment variable `LOG_LEVEL` to one of the following log levels: + +- error (only errors) +- warn (errors and warning) +- info (standard info regarding connectiviy and data from Automation protocol etc. including errors and warnings) +- debug (info level plus: data send and received from Audiomixer) +- trace (debug level plus: data send and received from Automation protocol) + +### Open GUI in browser: + +``` +localhost:1176 (or whatever ip you use for Sisyfos Nodejs/Docker) +``` + +#### Important - To enable settings: + +``` +localhost:1176/?settings=1 +``` + +To see the MiniMonitorView: + +``` +localhost:1176/?minimonitor=1 +``` + +If you want to disable the VU meters: + +``` +localhost:1176/?vu=0 +``` + +## Settings: + +### Show PFL Controls: + +As NEXT has been implemented, and PFL usually only work on on channel at a time, the PFL is only working correctly on 1:1 routed setups (And with the CasparCG protocol) + +(Mixer presets are stored in MixerProtocolPresets.js) + +### Following preset name are possible: + +- CasparCG + - use storage/default-casparcg.ccg as template and place you own file in storage folder. + - base your casparcg.config by the casparcg.config file in the same folder + - remember to activate OSC in the casparcg.config file to it points to Sisyfos +- Midas Master + - OSC protocol for Midas M32 and Behringer X32 + - Port 10023 + - Mixer preset loading (using .x32 files in storage folder) + - Protocol supports: + - Eq, Comp, Delay, Mix minus +- Lawo Mc2 + - Ember Protocol +- reaper + - OSC protocol for control Reaper (reaper.fm) +- Ardour Master + - OSC protocol for Ardour (www.ardour.org) + - Port 3819 + - The volume change in Ardour is on it´s channel faders. + - Todo: + - Meter calibration +- SSL System T - Broadcast Mixer + - SSL Automation Protocol for System T + - Port 10001 + - Set Protocol Latency to around 120ms +- Behringer xr master + - OSC protocol for Behringer XR12,16,18 + - Port 10024 + - In this version the Behringer is slave of Producers-Audio-mixer, so faders on the behringer is turned down when channel is of. +- DMXIS - Sisyfos control of DMX Lightcontroller + - Default Port is 8000 + - Controls Fader On/Off with preset level from Sisyfos. + - Easy implementation of state based lightcontrol from Automation. + - the PROTOCOL DELAY setting should be raised to 50ms, as DMXIS is responding a little slowly. +- midi + - Generic MIDI - still preminilary + - When using MIDI protocols, the PROTOCOL DELAY setting should be rised to at least 50ms +- Yamaha QL1 + - Ip - MIDI based Protocol + - Port 50000 + - Stable implementation of 2-ways Fader and Mute +- Studer Vista 1-5-9 (untested) + - mono, stereo, 51 channels fader level mute and Aux send from Sisyfos TO mixer + - No 2 way support for now +- Studer OnAir 3000 (untested) + - channel 1 to 24 fader level from Sisyfos TO mixer + - No 2 way support for now + +## Skaarhoj panels: + +Skaarhoj in RAW panel mode is supported for rotary buttons including labels. + +- HWC#1-xx = fader level on Sisyfos +- HWC#81-89 = enabled Monitor sends for Aux mix% on fader 1 +- HWC#91-99 = enabled Monitor sends for Aux mix% on fader 2 +- HWC#101-109 = enabled Monitor sends for Aux mix% on fader 3 + +The monitor sends are the same as those on the Channel Strip. + +## Automation Support: + +It´s possible to control the Producers-Audio-Mixer from an automationsystem, for it to act as middleware. + +## Set state: + +To set the state send these OSC commands from you Automation to ProducersAudioMixer Port: 5255: + +#### Set channel to PGM (optional: indiviaul fadetime): + +(the integer defines: 0 - Off, 1 - Pgm On, 2 - Voice Over) +(if second is missing it will take default fade value) +/ch/1/mix/pgm - integer: { 0, 1 or 2 } - float { fadetime in ms } + +#### Set channel to PST: + +/ch/1/mix/pst - integer: { 0, 1 or 2 } (the integer defines: 0 - Off, 1 - Pgm On, 2 - Voice Over) + +#### Mute channel: + +/ch/1/mute - integer: { 0, 1 } (the integer defines: 0 - Mute off, 1 - Mute On) + +#### Set channel faderlevel: + +/ch/1/mix/faderlevel - float {between 0 and 1} + +#### Set channel label: + +/ch/1/label - string {name of channel} + +#### Inject Command: + +Pass a command directly from Automation to Audiomixer +/inject + +#### Crossfade between PGM and PST: + +/take + +#### Set snap 1-xx to PST: + +/snap/1 + +#### Fade all channels to black (mute) + +/fadetoblack + +#### Clear all pst buttons + +/clearpst + +#### Hide or show channel strips on GUI: + +/ch/{value1}/visible - integer { 0 or 1 } + +## Get state: + +#### Get full state of all channels: + +/state/full - returns a json string with an array of channels: { pgmOn: boolean, pstOn: boolean, faderLevel: boolean } + +#### Get state channel PGM: + +/state/ch/1/mix/pgm - returns pgm state integer { 0 or 1 } + +#### get state channel PST: + +/state/ch/1/mix/pst - returns pgm state integer { 0 or 1 } + +#### Get state channel faderlevel: + +/state/ch/1/mix/faderlevel - float {between 0 and 1} + +#### get state channel Mute: + +/state/ch/1/mute - returns mute state integer { 0 or 1 } + +#### Get state group PGM: + +/state/ch/1/mix/pgm - returns pgm state integer { 0 or 1 } + +#### get state group PST: + +/state/ch/1/mix/pst - returns pgm state integer { 0 or 1 } + +#### Get state group faderlevel: + +/state/ch/1/mix/faderlevel - float {between 0 and 1} + +## Check connectivity + +/ping/{value} +_In response to a ping, sisyfos will reply with /pong and the provided value OR 'offline' if Audiomixer is not connected_ + +## Localization: + +Localization can be found in: /client/i18n.ts + +If we end up with a huge amount of translations we move the translations to seperate files, but for now we keep it simple. diff --git a/client/assets/css/App.css b/client/assets/css/App.css deleted file mode 100644 index 01a8d9a1..00000000 --- a/client/assets/css/App.css +++ /dev/null @@ -1,13 +0,0 @@ -/* Main CSS file */ -body { - margin: 0; - padding: 0; - font-family: sans-serif; - background-color: black; - user-select: none; -} - -.App { - position: relative; - text-align: center; -} diff --git a/client/assets/css/ChanStrip.css b/client/assets/css/ChanStrip.css deleted file mode 100644 index b75ddc0b..00000000 --- a/client/assets/css/ChanStrip.css +++ /dev/null @@ -1,159 +0,0 @@ -.chan-strip-body { - position: relative; - top: 5px; - width: 620px; - height: 940px; - background-color: rgb(31, 31, 31); - border-color: rgb(70, 70, 70); - border-style: solid; - border-width: 4px; - border-radius: 8px; - text-align: left; - color: #fff; -} - -.chan-strip-body > .header { - margin-left: 40px; - margin-top: 10px; - width: 420px; - font-size: 240%; - color: #fff; -} - -.chan-strip-body > .parameters { - top: 5px; - left: 2px; - height: 900px; - overflow: auto; - text-align: center; - color: #fff; -} - -.parameters > .parameter-group { - display: flex; - top: 5px; - left: 2px; - margin-left: 90px; - overflow: auto; - text-align: center; - color: #fff; -} - -.parameter-group > .horizontal-space { - width: 150px; - height: 50px; -} - -.parameters > .group-text { - text-align: center; - line-height: 20px; - font-size: 110%; -} - -.zero-eq { - width: 63px; - height: 2px; - margin-left: -68px; - margin-right: 30px; - margin-top: 111px; -} - -.zero-comp { - width: 63px; - height: 2px; - margin-left: -68px; - margin-right: 30px; - margin-top: 81px; -} - -.zero-monitor { - width: 2px; - height: 20px; - margin-left: 10px; - margin-top: -150px; -} - -.parameters > .parameter-text { - list-style-type: none; - text-align: center; - margin-top: 15px; - line-height: 10px; - font-size: 100%; -} - -.parameter-group > .delayButtons { - width: 30px; - margin-top: 24px; -} - -.delayButtons > .delayTime { - outline : none; - -moz-outline : none; - color: white; - height: 45px; - width: 70px; - border-color: rgb(71, 71, 71); - background-color: rgb(53, 53, 53); - margin-left: -50px; - margin-top: 5px; - border-radius: 7px; -} - -.parameters > .monitor-sends { - list-style-type: none; - display: flex; - text-align: center; - margin-top: 15px; - margin-left: 1px; - padding: 0px; - line-height: 10px; - font-size: 95%; -} - -.header > .close { - position: fixed; - outline : none; - border-color: rgb(99, 99, 99); - background-color: rgb(27, 27, 27); - border-radius: 20px; - color: #fff; - width: 50px; - height: 50px; - font-size: 30px; - margin-top: 5px; - left: 550px; -} - -.header > button { - outline : none; - border-color: rgb(99, 99, 99); - background-color: rgb(27, 27, 27); - border-radius: 7px; - margin-left: 10px; - margin-top: 5px; - width: 180px; - font-size: 12px; - line-height: 40px; - color: #fff; -} - -.chan-strip-fader { - width: 10px; - height: 200px; - margin-left: 35px; - margin-right: 30px; - margin-top: 10px; - border-width: 0px; - border-style: solid; - border-radius: 8px; - background-color: rgb(17, 17, 17); -} - -.chan-strip-thumb { - margin-left: -20px; - width: 45px; - height: 49px; - border: 1px solid #c5c2c2; - border-radius: 8px; - background: linear-gradient(to top, #3a3a3a 0%, #c2c2c2 20%, hsl(0, 0%, 57%) 50%, #00a 1px, #919191 52%, #c2c2c2 80%, #3a3a3a 100%); -} diff --git a/client/assets/css/ChannelRouteSettings.css b/client/assets/css/ChannelRouteSettings.css deleted file mode 100644 index b55b9cc6..00000000 --- a/client/assets/css/ChannelRouteSettings.css +++ /dev/null @@ -1,74 +0,0 @@ -.channel-route-body { - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 400px; - overflow: auto; - max-height: 90vh; - background-color: rgb(31, 31, 31); - border-color: rgb(124, 124, 124); - border-style: solid; - border-width: 4px; - text-align: left; - z-index: 2; - - color: #fff; -} - -.channel-route-body > h2 { - border-bottom: 1px solid #999; - margin: 0; - padding: 10px 0; - line-height: 50px; - text-align: center; - -} - - -.channel-route-text { - color: dimgray; - margin: 0; - margin-left: 40px; - padding: 0px 0; - line-height: 20px; - text-align: left; - font-size: 110%; -} - -.channel-route-text.checked { - font-weight: bold; - color: white; -} - -.channel-route-body > .close { - position: absolute; - outline : none; - border-color: rgb(99, 99, 99); - background-color: rgb(27, 27, 27); - border-radius: 100%; - display: block; - color: #fff; - width: 50px; - height: 50px; - font-size: 30px; - line-height: 50px; - top: -5px; - right: 9px; -} - -.channel-route-body > button { - line-height: 10px; - outline : none; - border-color: rgb(99, 99, 99); - background-color: rgb(27, 27, 27); - margin-right: 10px; - margin-top: 15px; - margin-bottom: 15px; - margin-left: 10px; - border-radius: 7px; - color: #fff; - width: 34%; - font-size: 10px; - line-height: 50px; -} diff --git a/client/assets/css/Channels.css b/client/assets/css/Channels.css deleted file mode 100644 index 0d05a6b2..00000000 --- a/client/assets/css/Channels.css +++ /dev/null @@ -1,153 +0,0 @@ -.channels-body { - display: flex; - flex-direction: row; - background-color: black; - min-height: 760px; -} - -.channels-body > .closedChanStrip { - margin-left: -630px; - transition: margin 300ms; -} - -.channels-body > .openChanStrip { - margin-left: 0px; - transition: margin 800ms; -} - -.channels-mix-body { - position: fixed; - z-index: 2; - right: -4px; - padding-right: 0px; - width: 100px; - min-height: 950px; - color: white; - background: linear-gradient(#2f2f2f 0px,#2f2f2f 790px, rgb(0, 0, 0) 1px, #2f2f2f 800px, #2f2f2f 100%); - margin: 4px; - border-radius: 9px; - border-color: rgb(80, 80, 80); - border-style: solid; - border-width: 1px; -} - -.channels-show-mixer-online { - outline : none; - -moz-outline : none; - color: rgb(255, 255, 255); - height: 60px; - width: 90px; - border-color: rgb(71, 71, 71); - background-color: rgb(219, 1, 1); - margin-left: 5px; - margin-right: 4px; - margin-top: 10px; - border-radius: 7px; -} - -.channels-show-mixer-online.connected { - background-color: rgb(9, 107, 0); - color: white; -} - -.channels-show-snaps-button { - outline : none; - -moz-outline : none; - color: white; - height: 60px; - width: 90px; - border-color: rgb(71, 71, 71); - background-color: rgb(53, 53, 53); - margin-left: 5px; - margin-right: 4px; - margin-top: 10px; - border-radius: 7px; -} - - -.channels-show-settings-button { - outline : none; - -moz-outline : none; - color: white; - height: 60px; - width: 90px; - border-color: rgb(71, 71, 71); - background-color: rgb(53, 53, 53); - margin-left: 5px; - margin-right: 4px; - margin-top: 10px; - border-radius: 7px; -} - - -.channels-show-storage-button { - outline : none; - -moz-outline : none; - color: white; - height: 60px; - width: 90px; - border-color: rgb(71, 71, 71); - background-color: rgb(53, 53, 53); - margin-left: 5px; - margin-right: 4px; - margin-top: 10px; - border-radius: 7px; -} - - -.channels-mix-button { - outline : none; - -moz-outline : none; - color: white; - height: 90px; - width: 90px; - border-color: rgb(139, 139, 139); - background-color: rgb(65, 65, 65); - margin-left: 4px; - margin-right: 4px; - margin-top: 50px; - border-radius: 7px; -} - - -.channels-clear-button { - outline : none; - -moz-outline : none; - color: white; - height: 90px; - width: 90px; - border-color: rgb(99, 99, 99); - background-color: rgb(19, 19, 19); - margin-left: 4px; - margin-right: 4px; - margin-top: 50px; - border-radius: 7px; -} - -.channels-snap-mix-body { - margin-top: 58px; -} - -.channels-snap-mix-line { - margin-top: 4px; - background-color: #2b2b2b; -} - -.channels-snap-mix-button { - outline : none; - -moz-outline : none; - background-color: rgb(199, 202, 0); - color: rgb(44, 44, 44); - margin-left: 20px; - margin-top: 4px; - margin-bottom: 4px; - height: 25px; - width: 60px; - border-radius: 7px; - border-color: rgb(99, 99, 99); - white-space: nowrap; -} - -.channels-snap-mix-line:last-of-type { - margin-bottom: 51px; -} diff --git a/client/assets/css/NoUiSlider.css b/client/assets/css/NoUiSlider.css deleted file mode 100644 index 661323c4..00000000 --- a/client/assets/css/NoUiSlider.css +++ /dev/null @@ -1,312 +0,0 @@ -/*! nouislider - 14.1.1 - 12/15/2019 */ -/* Functional styling; - * These styles are required for noUiSlider to function. - * You don't need to change these rules to apply your design. - */ -.noUi-target, -.noUi-target * { - -webkit-touch-callout: none; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - -webkit-user-select: none; - -ms-touch-action: none; - touch-action: none; - -ms-user-select: none; - -moz-user-select: none; - user-select: none; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.noUi-target { - position: relative; -} -.noUi-base, -.noUi-connects { - width: 100%; - height: 100%; - position: relative; - z-index: 1; -} -/* Wrapper for all connect elements. - */ -.noUi-connects { - overflow: hidden; - z-index: 0; -} -.noUi-connect, -.noUi-origin { - will-change: transform; - position: absolute; - z-index: 1; - top: 0; - right: 0; - -ms-transform-origin: 0 0; - -webkit-transform-origin: 0 0; - -webkit-transform-style: preserve-3d; - transform-origin: 0 0; - transform-style: flat; -} -.noUi-connect { - height: 100%; - width: 100%; -} -.noUi-origin { - height: 10%; - width: 10%; -} -/* Offset direction - */ -.noUi-txt-dir-rtl.noUi-horizontal .noUi-origin { - left: 0; - right: auto; -} -/* Give origins 0 height/width so they don't interfere with clicking the - * connect elements. - */ -.noUi-vertical .noUi-origin { - width: 0; -} -.noUi-horizontal .noUi-origin { - height: 0; -} -.noUi-handle { - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - position: absolute; -} -.noUi-touch-area { - height: 100%; - width: 100%; -} -.noUi-state-tap .noUi-connect, -.noUi-state-tap .noUi-origin { - -webkit-transition: transform 0.3s; - transition: transform 0.3s; -} -.noUi-state-drag * { - cursor: inherit !important; -} -/* Slider size and handle placement; - */ -.noUi-horizontal { - height: 18px; -} -.noUi-horizontal .noUi-handle { - width: 34px; - height: 28px; - right: -17px; - top: -6px; -} -.noUi-vertical { - width: 18px; -} -.noUi-vertical .noUi-handle { - width: 49px; - height: 75px; - right: -20px; - top: -27px; -} -.noUi-txt-dir-rtl.noUi-horizontal .noUi-handle { - left: -17px; - right: auto; -} -/* Styling; - * Giving the connect element a border radius causes issues with using transform: scale - */ -.noUi-target { - background: #FAFAFA; - border-radius: 4px; - border: 1px solid #D3D3D3; - box-shadow: inset 0 1px 1px #F0F0F0, 0 3px 6px -5px #BBB; -} -.noUi-connects { - border-radius: 3px; -} -.noUi-connect { - background: #3FB8AF; -} -/* Handles and cursors; - */ -.noUi-draggable { - cursor: ew-resize; -} -.noUi-vertical .noUi-draggable { - cursor: ns-resize; -} -.noUi-handle { - border: 1px solid #c5c2c2; - border-radius: 8px; - background: linear-gradient(to top, #3a3a3a 0%, #c2c2c2 20%, hsl(0, 0%, 57%) 50%, #00a 1px, #919191 52%, #c2c2c2 80%, #3a3a3a 100%); - cursor: default; -} - -.pgm-on .noUi-handle { - border: 1px solid rgb(253, 60, 60); - background: linear-gradient(to top, #3a1d1d 0%, #c04d4d 20%, #811919 50%, #00a 1px, #8a2626 52%, #bd5151 80%, #411f1f 100%); -} - -.vo-on .noUi-handle { - border: 1px solid rgb(252, 255, 86); - background: linear-gradient(to top, #353006 0%, #c59327 20%, #856b14 50%, #00a 1px, #866724 52%, #cca22d 80%, #463b0a 100%); -} - -.mute-on .noUi-handle { - border: 1px solid rgb(58, 58, 58); - background: linear-gradient(to top, #111111 0%, #252525 20%, #2b2b2b 50%, rgb(56, 56, 56) 1px, #292929 52%, #222222 80%, #222222 100%); -} - -.noUi-active { - box-shadow: inset 0 0 1px #FFF, inset 0 1px 7px #DDD, 0 3px 6px -3px #BBB; -} -/* Handle stripes; - */ -.noUi-handle:after { - content: ""; - display: block; - position: absolute; - height: 14px; - width: 1px; - background: rgba(0, 0, 0, 0); - left: 14px; - top: 6px; -} -.noUi-handle:after { - left: 17px; -} -.noUi-vertical .noUi-handle:before, -.noUi-vertical .noUi-handle:after { - width: 14px; - height: 1px; - left: 6px; - top: 14px; -} -.noUi-vertical .noUi-handle:after { - top: 17px; -} -/* Disabled state; - */ -[disabled] .noUi-connect { - background: #B8B8B8; -} -[disabled].noUi-target, -[disabled].noUi-handle, -[disabled] .noUi-handle { - cursor: not-allowed; -} -/* Base; - * - */ -.noUi-pips, -.noUi-pips * { - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.noUi-pips { - position: absolute; - color: #999; -} -/* Values; - * - */ -.noUi-value { - position: absolute; - white-space: nowrap; - text-align: center; -} -.noUi-value-sub { - color: #ccc; - font-size: 10px; -} -/* Markings; - * - */ -.noUi-marker { - position: absolute; - background: #CCC; -} -.noUi-marker-sub { - background: #AAA; -} -.noUi-marker-large { - background: #AAA; -} -/* Horizontal layout; - * - */ -.noUi-pips-horizontal { - padding: 10px 0; - height: 80px; - top: 100%; - left: 0; - width: 100%; -} -.noUi-value-horizontal { - -webkit-transform: translate(-50%, 50%); - transform: translate(-50%, 50%); -} -.noUi-rtl .noUi-value-horizontal { - -webkit-transform: translate(50%, 50%); - transform: translate(50%, 50%); -} -.noUi-marker-horizontal.noUi-marker { - margin-left: -1px; - width: 2px; - height: 5px; -} -.noUi-marker-horizontal.noUi-marker-sub { - height: 10px; -} -.noUi-marker-horizontal.noUi-marker-large { - height: 15px; -} -/* Vertical layout; - * - */ -.noUi-pips-vertical { - padding: 0 10px; - height: 100%; - top: 0; - left: 100%; -} -.noUi-value-vertical { - -webkit-transform: translate(0, -50%); - transform: translate(0, -50%); - padding-left: 25px; -} -.noUi-rtl .noUi-value-vertical { - -webkit-transform: translate(0, 50%); - transform: translate(0, 50%); -} -.noUi-marker-vertical.noUi-marker { - width: 5px; - height: 2px; - margin-top: -1px; -} -.noUi-marker-vertical.noUi-marker-sub { - width: 10px; -} -.noUi-marker-vertical.noUi-marker-large { - width: 15px; -} -.noUi-tooltip { - display: block; - position: absolute; - border: 1px solid #D9D9D9; - border-radius: 3px; - background: #fff; - color: #000; - padding: 5px; - text-align: center; - white-space: nowrap; -} -.noUi-horizontal .noUi-tooltip { - -webkit-transform: translate(-50%, 0); - transform: translate(-50%, 0); - left: 50%; - bottom: 120%; -} -.noUi-vertical .noUi-tooltip { - -webkit-transform: translate(0, -50%); - transform: translate(0, -50%); - top: 50%; - right: 120%; -} diff --git a/client/components/App.tsx b/client/components/App.tsx deleted file mode 100644 index 85ea2cea..00000000 --- a/client/components/App.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import * as React from 'react'; -import { connect } from "react-redux"; -import { IStore } from '../../server/reducers/indexReducer'; - - -import '../assets/css/App.css'; -import Channels from './Channels'; -import Settings from './Settings'; -import Storage from './RoutingStorage' - -export interface IAppProps { - store: IStore -} - -class App extends React.Component { - - constructor(props: IAppProps) { - super(props) - } - - componentWillMount() { - console.log('http args : ', window.location.search.includes('settings=0')) - window.socketIoClient.emit('get-mixerprotocol', 'get selected mixerprotocol') - window.socketIoClient.emit('get-store', 'update local store'); - window.socketIoClient.emit('get-settings', 'update local settings'); - this.iFrameFocusHandler() - } - - public shouldComponentUpdate(nextProps: IAppProps) { - return ( - nextProps.store.settings[0].showSettings != this.props.store.settings[0].showSettings - || nextProps.store.settings[0].showStorage != this.props.store.settings[0].showStorage - ) - } - - sendSofieMessage(type: string, payload?: any | '', replyTo?: string | '') { - window.top.postMessage({ - id: Date.now().toString(), - replyToId: replyTo, - type: type, - payload: payload - }, "*"); - } - - iFrameFocusHandler() { - if (window.top !== window.self) { - this.sendSofieMessage('hello') - document.addEventListener('click', (e) => { - e.preventDefault() - this.sendSofieMessage('focus_in') - }, true) - window.addEventListener('message', (event) => { - try { - const message = event.data - if (!message || !message.type) return; - switch (message.type) { - case 'welcome': - console.log('Hosted by: ' + message.payload); - // finish three-way handshake - this.sendSofieMessage('ack', undefined, message.id); - break; - - } - } catch (e) { - console.log('Error Sofie API') - } - }) - } - } - - render() { - return ( -
- - {this.props.store.settings[0].showStorage ? : null} - {this.props.store.settings[0].showSettings ? : null} -
- ) - } -} - - -const mapStateToProps = (state: any): IAppProps => { - return { - store: state - } -} - -export default connect(mapStateToProps)(App) as any; diff --git a/client/components/CcgChannelSettings.tsx b/client/components/CcgChannelSettings.tsx deleted file mode 100644 index a027f359..00000000 --- a/client/components/CcgChannelSettings.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; - -import '../assets/css/CcgChannelSettings.css'; -import { ICasparCGMixerGeometry } from '../../server/constants/MixerProtocolInterface'; -import { Store } from 'redux'; -import { connect } from 'react-redux'; -import { SOCKET_SET_INPUT_OPTION } from '../../server/constants/SOCKET_IO_DISPATCHERS'; - -interface IChannelSettingsInjectProps { - label: string, - mixerProtocol: string, - sourceOption: string -} - -interface IChannelProps { - channelIndex: number -} - -class CcgChannelInputSettings extends React.PureComponent { - mixerProtocol: ICasparCGMixerGeometry | undefined; - - constructor(props: any) { - super(props); - const protocol = window.mixerProtocol as ICasparCGMixerGeometry; - if (protocol.sourceOptions) { - this.mixerProtocol = protocol; - } - } - - handleOption = (prop: string, option: string) => { - window.socketIoClient.emit( SOCKET_SET_INPUT_OPTION, - { - channel: this.props.channelIndex, - prop: prop, - option: option - } - ) - } - - render() { - return ( -
-

{this.props.label || ("CH " + (this.props.channelIndex + 1))} INPUT :

- {this.mixerProtocol && - this.mixerProtocol.sourceOptions && - Object.getOwnPropertyNames(this.mixerProtocol.sourceOptions.options).map(prop => { - return ( -
- {Object.getOwnPropertyNames(this.mixerProtocol!.sourceOptions!.options[prop]).map(option => { - return - }) || null} -
- ) - }) - } -
- ) - } -} - -const mapStateToProps = (state: any, props: any): IChannelSettingsInjectProps => { - return { - label: state.channels[0].channel[props.channelIndex].label, - mixerProtocol: state.settings[0].mixerProtocol, - sourceOption: (state.channels[0].channel[props.channelIndex].private || {})['channel_layout'] - } -} - -export default connect(mapStateToProps)(CcgChannelInputSettings) as any; diff --git a/client/components/ChanStrip.tsx b/client/components/ChanStrip.tsx deleted file mode 100644 index 058dbf2a..00000000 --- a/client/components/ChanStrip.tsx +++ /dev/null @@ -1,498 +0,0 @@ -import React from 'react'; -import ReactSlider from 'react-slider' - -import '../assets/css/ChanStrip.css'; -import { Store } from 'redux'; -import { connect } from 'react-redux'; -import { - TOGGLE_SHOW_CHAN_STRIP, - TOGGLE_SHOW_OPTION, - TOGGLE_SHOW_MONITOR_OPTIONS - } from '../../server/reducers/settingsActions' -import { IFader } from '../../server/reducers/fadersReducer' -import { - SOCKET_SET_THRESHOLD, - SOCKET_SET_RATIO, - SOCKET_SET_DELAY_TIME, - SOCKET_SET_LOW, - SOCKET_SET_LO_MID, - SOCKET_SET_MID, - SOCKET_SET_HIGH, - SOCKET_SET_AUX_LEVEL -} from '../../server/constants/SOCKET_IO_DISPATCHERS'; -import CcgChannelInputSettings from './CcgChannelSettings'; - -interface IChanStripInjectProps { - label: string, - selectedProtocol: string, - numberOfChannelsInType: Array, - channel: Array - fader: Array - auxSendIndex: number - offtubeMode: boolean -} - -interface IChanStripProps { - faderIndex: number -} - -class ChanStrip extends React.PureComponent { - - constructor(props: any) { - super(props); - } - - handleShowRoutingOptions() { - this.props.dispatch({ - type: TOGGLE_SHOW_OPTION, - channel: this.props.faderIndex - }); - this.props.dispatch({ - type: TOGGLE_SHOW_CHAN_STRIP, - channel: -1 - }); - - } - - handleShowMonitorOptions() { - this.props.dispatch({ - type: TOGGLE_SHOW_MONITOR_OPTIONS, - channel: this.props.faderIndex - }); - this.props.dispatch({ - type: TOGGLE_SHOW_CHAN_STRIP, - channel: -1 - }); - } - - handleClose = () => { - this.props.dispatch({ - type: TOGGLE_SHOW_CHAN_STRIP, - channel: -1 - }); - } - - handleThreshold(event: any) { - window.socketIoClient.emit( SOCKET_SET_THRESHOLD, - { - channel: this.props.faderIndex, - level: parseFloat(event) - } - ) - } - handleRatio(event: any) { - window.socketIoClient.emit( SOCKET_SET_RATIO, - { - channel: this.props.faderIndex, - level: parseFloat(event) - } - ) - } - - handleDelay(event: any) { - window.socketIoClient.emit( SOCKET_SET_DELAY_TIME, - { - channel: this.props.faderIndex, - delayTime: parseFloat(event) - } - ) - } - - changeDelay(currentValue: number, addValue: number) { - window.socketIoClient.emit( SOCKET_SET_DELAY_TIME, - { - channel: this.props.faderIndex, - delayTime: currentValue + addValue - } - ) - } - - handleLow(event: any) { - window.socketIoClient.emit( SOCKET_SET_LOW, - { - channel: this.props.faderIndex, - level: parseFloat(event) - } - ) - } - - handleLoMid(event: any) { - window.socketIoClient.emit( SOCKET_SET_LO_MID, - { - channel: this.props.faderIndex, - level: parseFloat(event) - } - ) - } - - handleMid(event: any) { - window.socketIoClient.emit( SOCKET_SET_MID, - { - channel: this.props.faderIndex, - level: parseFloat(event) - } - ) - } - handleHigh(event: any) { - window.socketIoClient.emit( SOCKET_SET_HIGH, - { - channel: this.props.faderIndex, - level: parseFloat(event) - } - ) - } - handleMonitorLevel(event: any, channelIndex: number) { - window.socketIoClient.emit( - SOCKET_SET_AUX_LEVEL, - { - channel: channelIndex, - auxIndex: this.props.auxSendIndex, - level: parseFloat(event) - } - ) - } - - threshold() { - return ( -
- Threshold - { - this.handleThreshold(event) - }} - /> -
- ) - } - - - ratio() { - return ( -
- Ratio - { - this.handleRatio(event) - }} - /> -
- ) - } - - delay() { - return ( - -
- - - - -
-
- {Math.round(500*(this.props.fader[this.props.faderIndex].delayTime || 0))} ms - { - this.handleDelay(event) - }} - /> -
-
- ) - } - - low() { - return ( -
- Low - { - this.handleLow(event) - }} - /> -
- ) - } - - loMid() { - return ( -
- Lo-Mid - { - this.handleLoMid(event) - }} - /> -
- ) - } - - mid() { - return ( -
- Hi-Mid - { - this.handleMid(event) - }} - /> -
- ) - } - - high() { - return ( -
- High - { - this.handleHigh(event) - }} - /> -
- ) - } - - monitor(channelIndex: number) { - let faderIndex = this.props.channel[channelIndex].assignedFader - if (faderIndex === -1) return null - let monitorName = this.props.fader[faderIndex] ? this.props.fader[faderIndex].label : '' - if (monitorName === '') { - monitorName = 'Fader ' + String(this.props.channel[channelIndex].assignedFader + 1) - } - return ( -
  • - {monitorName} - { - this.handleMonitorLevel(event, channelIndex) - }} - /> -

    _______

    -
  • - ) - } - parameters() { - if (this.props.selectedProtocol.includes("caspar")) { - return ( - - ) - } - else { - return ( -
    -
    - COMPRESSOR -       -       -       -       -       -       -     - DELAY -
    -
    - {this.threshold()} -

    ______

    - {this.ratio()} -

    ______

    -

    - {this.delay()} - -
    -
    -
    - {"EQUALIZER"} -
    -
    - {this.low()} -

    _______

    - {this.loMid()} -

    _______

    - {this.mid()} -

    _______

    - {this.high()} -

    _______

    -
    -
    -
    - {this.props.label || ("FADER " + (this.props.faderIndex + 1))} - {" - MONITOR MIX MINUS"} -
    -
      - {this.props.channel.map((ch: any, index: number) => { - if (ch.auxLevel[this.props.auxSendIndex] >= 0) { - return this.monitor(index) - } - })} -
    -
    - ) - } - } - - render() { - if (this.props.faderIndex >= 0) { - return ( -
    -
    - {this.props.label || ("FADER " + (this.props.faderIndex + 1))} - - -
    -
    - {window.location.search.includes('settings=0') ? - null : - - } - {window.location.search.includes('settings=0') ? - null : - - } -
    -
    - {this.props.offtubeMode ? - this.parameters() - : null - } -
    - ) - } else { - return ( -
    -
    - ) - } - - } -} - -const mapStateToProps = (state: any, props: any): IChanStripInjectProps => { - let inject: IChanStripInjectProps = { - label: '', - selectedProtocol: state.settings[0].mixerProtocol, - numberOfChannelsInType: state.settings[0].numberOfChannelsInType, - channel: state.channels[0].channel, - fader: state.faders[0].fader, - auxSendIndex: -1, - offtubeMode: state.settings[0].offtubeMode - } - if (props.faderIndex >= 0) { - inject = { - label: state.faders[0].fader[props.faderIndex].label, - selectedProtocol: state.settings[0].mixerProtocol, - numberOfChannelsInType: state.settings[0].numberOfChannelsInType, - channel: state.channels[0].channel, - fader: state.faders[0].fader, - auxSendIndex: state.faders[0].fader[props.faderIndex].monitor - 1, - offtubeMode: state.settings[0].offtubeMode - } - } - return inject -} - -export default connect(mapStateToProps)(ChanStrip) as any; diff --git a/client/components/Channel.tsx b/client/components/Channel.tsx deleted file mode 100644 index d007b325..00000000 --- a/client/components/Channel.tsx +++ /dev/null @@ -1,321 +0,0 @@ -import * as React from 'react'; -//@ts-ignore -import * as ClassNames from 'classnames'; -import { connect } from "react-redux"; -import VuMeter from './VuMeter'; -import { Store } from 'redux'; -import Nouislider from 'nouislider-react' -import '../assets/css/NoUiSlider.css' - -//assets: -import '../assets/css/Channel.css'; -import { SOCKET_TOGGLE_PGM, SOCKET_TOGGLE_VO, SOCKET_TOGGLE_PST, SOCKET_TOGGLE_PFL, SOCKET_TOGGLE_MUTE, SOCKET_SET_FADERLEVEL, SOCKET_TOGGLE_IGNORE } from '../../server/constants/SOCKET_IO_DISPATCHERS' -import { IFader } from '../../server/reducers/fadersReducer'; -import { IChannels } from '../../server/reducers/channelsReducer'; -import { ISettings } from '../../server/reducers/settingsReducer'; -import { TOGGLE_SHOW_CHAN_STRIP } from '../../server/reducers/settingsActions'; - -interface IChannelInjectProps { - channels: IChannels - fader: IFader - settings: ISettings - channelType: number, - channelTypeIndex: number, -} - -interface IChannelProps { - faderIndex: number -} - - -class Channel extends React.Component { - faderIndex: number; - - constructor(props: any) { - super(props); - this.faderIndex = this.props.faderIndex; - } - - public shouldComponentUpdate(nextProps: IChannelInjectProps) { - return ( - nextProps.fader.pgmOn != this.props.fader.pgmOn || - nextProps.fader.voOn != this.props.fader.voOn || - nextProps.fader.pstOn != this.props.fader.pstOn || - nextProps.fader.pflOn != this.props.fader.pflOn || - nextProps.fader.muteOn != this.props.fader.muteOn || - nextProps.fader.ignoreAutomation != this.props.fader.ignoreAutomation || - nextProps.fader.showChannel != this.props.fader.showChannel || - nextProps.fader.faderLevel != this.props.fader.faderLevel || - nextProps.fader.label != this.props.fader.label || - nextProps.settings.mixerProtocol != this.props.settings.mixerProtocol || - nextProps.settings.showSnaps != this.props.settings.showSnaps || - nextProps.settings.showPfl != this.props.settings.showPfl || - nextProps.settings.showChanStrip != this.props.settings.showChanStrip - ) - } - - handlePgm() { - window.socketIoClient.emit( SOCKET_TOGGLE_PGM, this.faderIndex) - } - - handleVo() { - window.socketIoClient.emit( SOCKET_TOGGLE_VO, this.faderIndex) - } - - handlePst() { - window.socketIoClient.emit( SOCKET_TOGGLE_PST, this.faderIndex) - } - - handlePfl() { - window.socketIoClient.emit( SOCKET_TOGGLE_PFL, this.faderIndex) - } - - handleMute() { - window.socketIoClient.emit( SOCKET_TOGGLE_MUTE, this.faderIndex) - } - - handleIgnore() { - window.socketIoClient.emit( SOCKET_TOGGLE_IGNORE, this.faderIndex) - } - - handleLevel(event: any) { - window.socketIoClient.emit( SOCKET_SET_FADERLEVEL, - { - 'faderIndex' :this.faderIndex, - 'level': parseFloat(event) - }) - } - - handleShowChanStrip() { - this.props.dispatch({ - type: TOGGLE_SHOW_CHAN_STRIP, - channel: this.faderIndex - }); - } - - fader() { - return ( - { - this.handleLevel(event); - }} - - /> - ) - } - - - pgmButton = () => { - return ( - - - ) - } - - - voButton = () => { - return ( - - - ) - } - - pstButton = () => { - return ( - - ) - } - - chanStripButton = () => { - return ( - - ) - } - - pflButton = () => { - return ( - - ) - } - - - ignoreButton = () => { - return ( - - ) - } - - muteButton = () => { - return ( - - ) - } - - render() { - return ( - this.props.fader.showChannel === false ? - null - : -
    - {this.ignoreButton()} - {this.muteButton()} -
    -

    _____

    - {this.fader()} - -
    - {this.pgmButton()} -
    - {this.props.settings.automationMode ? - - {this.voButton()} -
    -
    - : null - } - {!this.props.settings.showPfl ? - - {this.pstButton()} -
    -
    - : null - } - {this.props.settings.showPfl ? - - {this.pflButton()} -
    -
    - : null - } - - {this.chanStripButton()} -
    -
    -
    - ) - } -} - -const mapStateToProps = (state: any, props: any): IChannelInjectProps => { - return { - channels: state.channels[0].channel, - fader: state.faders[0].fader[props.faderIndex], - settings: state.settings[0], - channelType: 0, /* TODO: state.channels[0].channel[props.channelIndex].channelType, */ - channelTypeIndex: props.faderIndex ,/* TODO: state.channels[0].channel[props.channelIndex].channelTypeIndex, */ - } -} - -export default connect(mapStateToProps)(Channel) as any; diff --git a/client/components/ChannelMonitorOptions.tsx b/client/components/ChannelMonitorOptions.tsx deleted file mode 100644 index 333c4054..00000000 --- a/client/components/ChannelMonitorOptions.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import React, { ChangeEvent } from 'react'; -//@ts-ignore -import * as ClassNames from 'classnames'; - -import '../assets/css/ChannelMonitorOptions.css'; -import { Store } from 'redux'; -import { connect } from 'react-redux'; -import { TOGGLE_SHOW_MONITOR_OPTIONS } from '../../server/reducers/settingsActions' -import { ISettings } from '../../server/reducers/settingsReducer'; -import { SOCKET_SET_AUX_LEVEL, SOCKET_SET_FADER_MONITOR } from '../../server/constants/SOCKET_IO_DISPATCHERS'; - -interface IMonitorSettingsInjectProps { - label: string, - selectedProtocol: string, - numberOfChannelsInType: Array, - channel: Array - fader: Array - settings: ISettings -} - -interface IChannelProps { - faderIndex: number -} - -class ChannelMonitorOptions extends React.PureComponent { - faderIndex: number; - - constructor(props: any) { - super(props); - this.faderIndex = this.props.faderIndex; - } - - handleAssignChannel(channel: number, event: any) { - if (event.target.checked === false) { - if (window.confirm('Remove monitoring on ' + String(channel + 1))) { - window.socketIoClient.emit( - SOCKET_SET_AUX_LEVEL, - { - channel: channel, - auxIndex: this.props.fader[this.faderIndex].monitor - 1, - level: -1 - } - ) - } - } else { - if (window.confirm('Enable monitoring of Channel ' + String(channel + 1) + '?')) { - window.socketIoClient.emit( - SOCKET_SET_AUX_LEVEL, - { - channel: channel, - auxIndex: this.props.fader[this.faderIndex].monitor - 1, - level: 0 - } - ) - } - } - } - - handleClearMonitorRouting() { - if (window.confirm('This will remove all monitor assignments to Aux :' + String(this.props.fader[this.faderIndex].monitor))) { - this.props.channel.forEach((channel: any, index: number) => { - window.socketIoClient.emit( - SOCKET_SET_AUX_LEVEL, - { - channel: index, - auxIndex: this.props.fader[this.faderIndex].monitor - 1, - level: -1 - } - ) - }) - } - } - - handleMixMinusRouting() { - if (window.confirm('Send all channels to Aux: ' + String(this.props.fader[this.faderIndex].monitor))) { - this.props.channel.forEach((channel: any, index: number) => { - window.socketIoClient.emit( - SOCKET_SET_AUX_LEVEL, - { - channel: index, - auxIndex: this.props.fader[this.faderIndex].monitor - 1, - level: 0 - } - ) - }) - } - } - - handleSetAux = (event: ChangeEvent) => { - let value = parseFloat(event.target.value) || -1 - if (value > this.props.settings.numberOfAux || value < 0) { - value = -1 - } - window.socketIoClient.emit( - SOCKET_SET_FADER_MONITOR, - { - faderIndex: this.faderIndex, - auxIndex: value - } - ) - } - - - handleClose = () => { - this.props.dispatch({ - type: TOGGLE_SHOW_MONITOR_OPTIONS, - channel: this.faderIndex - }); - } - - render() { - return ( -
    -

    MONITOR ROUTE

    -

    {this.props.label || ("FADER " + (this.faderIndex + 1))}

    - - - -
    - - this.handleSetAux(event)} - /> -
    - {this.props.channel.map((channel: any, index: number) => { - return
    = 0 || false - })} - > - {(" Channel " + (index + 1) + " : ")} - = 0} - onChange={(event) => this.handleAssignChannel(index, event)} - /> - {this.props.channel[index].auxLevel[this.props.fader[this.faderIndex].monitor - 1] >= 0 - ? ("Monitor this") - : null - } -
    - }) - } -
    - ) - } - -} - -const mapStateToProps = (state: any, props: any): IMonitorSettingsInjectProps => { - return { - label: state.faders[0].fader[props.faderIndex].label, - selectedProtocol: state.settings[0].mixerProtocol, - numberOfChannelsInType: state.settings[0].numberOfChannelsInType, - channel: state.channels[0].channel, - fader: state.faders[0].fader, - settings: state.settings[0] - } -} - -export default connect(mapStateToProps)(ChannelMonitorOptions) as any; diff --git a/client/components/ChannelRouteSettings.tsx b/client/components/ChannelRouteSettings.tsx deleted file mode 100644 index 7facd584..00000000 --- a/client/components/ChannelRouteSettings.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import React from 'react'; -//@ts-ignore -import * as ClassNames from 'classnames'; - -import '../assets/css/ChannelRouteSettings.css'; -import { Store } from 'redux'; -import { connect } from 'react-redux'; -import { TOGGLE_SHOW_OPTION } from '../../server/reducers/settingsActions' -import { SOCKET_SET_ASSIGNED_FADER } from '../../server/constants/SOCKET_IO_DISPATCHERS'; - -interface IChannelSettingsInjectProps { - label: string, - selectedProtocol: string, - numberOfChannelsInType: Array, - channel: Array - fader: Array -} - -interface IChannelProps { - faderIndex: number -} - -class ChannelRouteSettings extends React.PureComponent { - faderIndex: number; - - constructor(props: any) { - super(props); - this.faderIndex = this.props.faderIndex; - } - - handleAssignChannel(channel: number, event: any) { - - if (event.target.checked === false) { - console.log('Unbinding Channel') - if (window.confirm('Unbind Channel ' + String(channel + 1) + ' from Fader ' + String(this.faderIndex + 1))) { - window.socketIoClient.emit( - SOCKET_SET_ASSIGNED_FADER, - { - channel: channel, - faderAssign: -1 - } - ) - } - } else { - console.log('Binding Channel') - if (window.confirm('Bind Channel ' + String(channel + 1) + ' to Fader ' + String(this.faderIndex + 1) + '?')) { - window.socketIoClient.emit( - SOCKET_SET_ASSIGNED_FADER, - { - channel: channel, - faderAssign: this.faderIndex - } - ) - } - } - } - - handleClearRouting() { - if (window.confirm('REMOVE ALL FADER ASSIGNMENTS????')) { - this.props.channel.forEach((channel: any, index: number) => { - window.socketIoClient.emit( - SOCKET_SET_ASSIGNED_FADER, - { - channel: index, - faderAssign: -1 - } - ) - }) - } - } - - handle11Routing() { - if (window.confirm('Reassign all Faders 1:1 to Channels????')) { - this.props.fader.forEach((fader: any, index: number) => { - if (this.props.channel.length > index) { - window.socketIoClient.emit( - SOCKET_SET_ASSIGNED_FADER, - { - channel: index, - faderAssign: index - } - ) - } - }) - } - } - - handleClose = () => { - this.props.dispatch({ - type: TOGGLE_SHOW_OPTION, - channel: this.faderIndex - }); - } - - render() { - return ( -
    -

    {this.props.label || ("FADER " + (this.faderIndex + 1))}

    - - - -
    - {this.props.channel.map((channel: any, index: number) => { - return
    - {(" Channel " + (index + 1) + " : ")} - this.handleAssignChannel(index, event)} - /> - {this.props.channel[index].assignedFader >= 0 - ? (" (Fader " + (this.props.channel[index].assignedFader + 1) + ")") - : ' (not assigned)'} -
    - }) - } -
    - ) - } -} - -const mapStateToProps = (state: any, props: any): IChannelSettingsInjectProps => { - return { - label: state.faders[0].fader[props.faderIndex].label, - selectedProtocol: state.settings[0].mixerProtocol, - numberOfChannelsInType: state.settings[0].numberOfChannelsInType, - channel: state.channels[0].channel, - fader: state.faders[0].fader, - } -} - -export default connect(mapStateToProps)(ChannelRouteSettings) as any; diff --git a/client/components/Channels.tsx b/client/components/Channels.tsx deleted file mode 100644 index 1d2490cc..00000000 --- a/client/components/Channels.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import * as React from 'react'; -import { connect } from "react-redux"; -//@ts-ignore -import * as ClassNames from 'classnames'; - -import Channel from './Channel'; -import '../assets/css/Channels.css'; -import { Store } from 'redux'; -import { - TOGGLE_SHOW_SETTINGS, - TOGGLE_SHOW_STORAGE -} from '../../server/reducers/settingsActions' -import ChannelRouteSettings from './ChannelRouteSettings'; -import ChanStrip from './ChanStrip' -import ChannelMonitorOptions from './ChannelMonitorOptions'; -import { IChannels } from '../../server/reducers/channelsReducer'; -import { IFader } from '../../server/reducers/fadersReducer'; -import { ISettings } from '../../server/reducers/settingsReducer'; -import { SOCKET_NEXT_MIX, SOCKET_CLEAR_PST, SOCKET_RESTART_SERVER } from '../../server/constants/SOCKET_IO_DISPATCHERS'; - -interface IChannelsInjectProps { - channels: IChannels - faders: IFader[] - settings: ISettings -} - -class Channels extends React.Component { - constructor(props: any) { - super(props); - this.props.settings.showMonitorOptions = -1 - } - - public shouldComponentUpdate(nextProps: IChannelsInjectProps) { - return this.props.settings.showOptions !== nextProps.settings.showOptions - || this.props.settings.showChanStrip !== nextProps.settings.showChanStrip - || this.props.settings.showMonitorOptions !== nextProps.settings.showMonitorOptions - || this.props.settings.mixerOnline !== nextProps.settings.mixerOnline - || this.props.faders.length !== nextProps.faders.length; - } - - handleMix() { - window.socketIoClient.emit(SOCKET_NEXT_MIX) - } - - handleClearAllPst() { - window.socketIoClient.emit(SOCKET_CLEAR_PST) - } - - handleReconnect() { - if (window.confirm('Are you sure you will restart server?')) { - window.socketIoClient.emit(SOCKET_RESTART_SERVER) - } - } - - - handleShowSettings() { - this.props.dispatch({ - type: TOGGLE_SHOW_SETTINGS, - }); - } - - handleShowStorage() { - this.props.dispatch({ - type: TOGGLE_SHOW_STORAGE, - }); - } - - render() { - return ( -
    - {(typeof this.props.settings.showOptions === 'number') ? - - : - null - } - {(this.props.settings.showChanStrip >= 0) ? -
    - -
    - : -
    - -
    - } - {(this.props.settings.showMonitorOptions >= 0) ? - - : - null - } - {this.props.faders.map((none: any, index: number) => { - return - }) - } -
    -
    - {this.props.settings.mixerOnline ? - - : - - } - - {window.location.search.includes('settings=0') ? - null : - - } - {window.location.search.includes('settings=0') ? - null : - - } - -
    - - {} -
    -
    -
    - ) - } -} - - -const mapStateToProps = (state: any): IChannelsInjectProps => { - return { - channels: state.channels[0].channel, - faders: state.faders[0].fader, - settings: state.settings[0] - } -} - -export default connect(mapStateToProps)(Channels); diff --git a/client/components/RoutingStorage.tsx b/client/components/RoutingStorage.tsx deleted file mode 100644 index bd3a3fdf..00000000 --- a/client/components/RoutingStorage.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import React from 'react'; - -import '../assets/css/RoutingStorage.css'; -import { Store } from 'redux'; -import { connect } from 'react-redux'; -import { TOGGLE_SHOW_STORAGE } from '../../server/reducers/settingsActions' -import { - SOCKET_GET_SNAPSHOT_LIST, - SOCKET_LOAD_SNAPSHOT, - SOCKET_SAVE_SNAPSHOT, - SOCKET_GET_CCG_LIST, - SOCKET_SAVE_CCG_FILE -} from '../../server/constants/SOCKET_IO_DISPATCHERS'; - -interface IStorageProps { - load: any - save: any -} -class Storage extends React.PureComponent { - fileList: string[] = [] - loadSnapshot: any - saveSnapshot: any - - constructor(props: any) { - super(props); - this.loadSnapshot = this.props.load - this.saveSnapshot = this.props.save - - //Bindings: - this.ListSnapshotFiles = this.ListSnapshotFiles.bind(this) - this.ListCcgFiles = this.ListCcgFiles.bind(this) - this.loadFile = this.loadFile.bind(this) - this.saveFile = this.saveFile.bind(this) - } - - handleClose = () => { - this.props.dispatch({ - type: TOGGLE_SHOW_STORAGE - }); - } - - saveFile() { - let fileName = window.prompt('Enter filename :', 'newfile') - if (window.confirm('Are you sure you will save ' + fileName + ' as new routing setup?')) - { - console.log('Saving file') - window.socketIoClient.emit(SOCKET_SAVE_SNAPSHOT, fileName + '.shot') - } - this.handleClose() - } - - loadFile(event: any) { - if (window.confirm('Are you sure you will load a new routing setup?')) - { - console.log('Loading files') - window.socketIoClient.emit(SOCKET_LOAD_SNAPSHOT, event.target.textContent) - } - this.handleClose() - } - loadCcgFile(event: any) { - if (window.confirm('Are you sure you will load a CasparCG setup?')) - { - console.log('Setting default CasparCG file') - window.socketIoClient.emit(SOCKET_SAVE_CCG_FILE, event.target.textContent) - } - this.handleClose() - } - - - ListSnapshotFiles() { - window.socketIoClient.emit(SOCKET_GET_SNAPSHOT_LIST) - const listItems = window.snapshotFileList.map((file: string, index: number) => { - return ( -
  • - {file} -
  • ) - }); - return ( -
      - {listItems} -
    - ); - } - - ListCcgFiles() { - window.socketIoClient.emit(SOCKET_GET_CCG_LIST) - const listItems = window.ccgFileList.map((file: string, index: number) => { - return ( -
  • - {file} -
  • - ) - }) - return ( -
      - {listItems} -
    - ) - } - - render() { - return ( -
    - -

    STORAGE

    -
    -

    SAVE ROUTING :

    - -
    -

    LOAD ROUTING :

    - - {window.ccgFileList.length > 0 ? -
    -
    -

    LOAD CASPARCG :

    - -
    - : null - } -
    - ) - } - -} - -const mapStateToProps = (state: any, props: any): any => { - return { - load: props.load, - save: props.save - } -} - -export default connect(mapStateToProps)(Storage) as any; diff --git a/client/components/Settings.tsx b/client/components/Settings.tsx deleted file mode 100644 index 401c9ff2..00000000 --- a/client/components/Settings.tsx +++ /dev/null @@ -1,369 +0,0 @@ -import * as React from 'react'; -import { connect } from "react-redux"; -import Select from 'react-select'; -import WebMidi from 'webmidi'; -import { IAppProps } from './App'; - -//Utils: -import '../assets/css/Settings.css'; -import { ISettings } from '../../server/reducers/settingsReducer'; -import { SHOW_CHANNEL } from '../../server/reducers/faderActions' -import { Store } from 'redux'; -import { ChangeEvent } from 'react'; -import { SOCKET_SAVE_SETTINGS } from '../../server/constants/SOCKET_IO_DISPATCHERS'; -import { TOGGLE_SHOW_SETTINGS } from '../../server/reducers/settingsActions'; - -//Set style for Select dropdown component: -const selectorColorStyles = { - control: - (styles: any) => ({ - ...styles, backgroundColor: '#676767', color: 'white', border: 0, width: 500, marginLeft: 100 - } - ), - option: (styles: any) => { - return { - backgroundColor: '#AAAAAA', - color: 'white' - }; - }, - singleValue: (styles: any) => ({ ...styles, color: 'white' }), -}; - -interface IState { - settings: ISettings -} - - -class Settings extends React.PureComponent { - selectedProtocol: any; - midiInputPortList: any; - midiOutputPortList: any; - - - constructor(props: any) { - super(props); - - this.state = { - settings: this.props.store.settings[0], - }; - //Initialise list of Midi ports: - this.findMidiPorts(); - } - - findMidiPorts = () => { - WebMidi.enable((err) => { - - if (err) { - console.log("WebMidi could not be enabled.", err); - } - - // Viewing available inputs and outputs - console.log("Midi inputs : ", WebMidi.inputs); - console.log("Midi outputs : ", WebMidi.outputs); - }); - this.midiInputPortList = WebMidi.inputs.map((input) => { - return {"label": input.name, "value": input.name} - }); - this.midiOutputPortList = WebMidi.outputs.map((output) => { - return {"label": output.name, "value": output.name} - }); - - } - - handleRemoteMidiInputPort = (selectedOption: any) => { - var settingsCopy= Object.assign({}, this.state.settings); - settingsCopy.remoteFaderMidiInputPort = selectedOption.value; - this.setState( - {settings: settingsCopy} - ); - } - - handleRemoteMidiOutputPort = (selectedOption: any) => { - var settingsCopy = Object.assign({}, this.state.settings); - settingsCopy.remoteFaderMidiOutputPort = selectedOption.value; - this.setState( - {settings: settingsCopy} - ); - } - - - handleMixerMidiInputPort = (selectedOption: any) => { - var settingsCopy= Object.assign({}, this.state.settings); - settingsCopy.mixerMidiInputPort = selectedOption.value; - this.setState( - {settings: settingsCopy} - ); - } - - handleMixerMidiOutputPort = (selectedOption: any) => { - var settingsCopy = Object.assign({}, this.state.settings); - settingsCopy.mixerMidiOutputPort = selectedOption.value; - this.setState( - {settings: settingsCopy} - ); - } - - - handleChange = (event: ChangeEvent) => { - var settingsCopy = Object.assign({}, this.state.settings); - if (event.target.type === "checkbox") { - (settingsCopy as any)[event.target.name] = !!event.target.checked; - } else { - (settingsCopy as any)[event.target.name] = event.target.value; - } - this.setState( - {settings: settingsCopy} - ); - } - - - handleProtocolChange = (selectedOption: any) => { - var settingsCopy= Object.assign({}, this.state.settings); - settingsCopy.mixerProtocol = selectedOption.value; - window.mixerProtocol = window.mixerProtocolPresets[settingsCopy.mixerProtocol] - this.setState( - {settings: settingsCopy} - ); - } - - handleNumberOfChannels = (index: number, event: any) => { - let settingsCopy= Object.assign({}, this.state.settings); - settingsCopy.numberOfChannelsInType[index] = parseInt(event.target.value); - this.setState( - {settings: settingsCopy} - ); - } - - handleShowChannel = (index: number, event: any) => { - this.props.dispatch({ - type: SHOW_CHANNEL, - channel: index, - showChannel: event.target.checked - }); - } - - handleShowAllChannels = () => { - this.props.store.channels[0].channel.map((channel: any, index: number) => { - this.props.dispatch({ - type: SHOW_CHANNEL, - channel: index, - showChannel: true - }); - }); - } - - - handleHideAllChannels = () => { - this.props.store.channels[0].channel.map((channel: any, index: number) => { - this.props.dispatch({ - type: SHOW_CHANNEL, - channel: index, - showChannel: false - }); - }); - } - - handleSave = () => { - let settingsCopy= Object.assign({}, this.state.settings); - settingsCopy.showSettings = false; - window.socketIoClient.emit( SOCKET_SAVE_SETTINGS, settingsCopy) - location.reload(); - } - - handleCancel = () => { - this.props.dispatch({ - type: TOGGLE_SHOW_SETTINGS, - }); - } - - renderChannelTypeSettings = () => { - return ( -
    -
    - NUMBER OF CHANNELTYPES: -
    - {window.mixerProtocol.channelTypes.map((item: any, index: number) => { - return - -
    -
    - })} -
    - ) - } - - renderMixerMidiSettings = () => { - return ( -
    -
    - MIXER MIDI SETTINGS: -
    -
    - Mixer Midi Input Port : -
    - -
    -
    - ) - } - - render() { - return ( -
    -
    - MIXER SETTINGS: -
    - - - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - {window.mixerProtocol.protocol === "MIDI" ? this.renderMixerMidiSettings() : ""} -
    - {this.renderChannelTypeSettings()} -
    - - -
    - ) - } -} - -const mapStateToProps = (state: any): IAppProps => { - return { - store: state - } -} - -export default connect(mapStateToProps)(Settings) as any; diff --git a/client/components/VuMeter.tsx b/client/components/VuMeter.tsx deleted file mode 100644 index 4c04a57c..00000000 --- a/client/components/VuMeter.tsx +++ /dev/null @@ -1,164 +0,0 @@ -import * as React from 'react'; -import { connect } from "react-redux"; - -//assets: -import '../assets/css/VuMeter.css'; -//Utils: - -export interface IVuMeterInjectedProps { - showSnaps: boolean - vuVal: number -} - -interface IVuMeterProps { - faderIndex: number -} - -export class VuMeter extends React.PureComponent { - canvas: HTMLCanvasElement | undefined; - - totalPeak: number = 0; - windowPeak: number = 0; - windowLast: number = 0; - WINDOW: number = 2000; - - constructor(props: any) { - super(props); - - } - - totalHeight = () => { - return (this.props.showSnaps ? 1 : 2) * 200 / (window.mixerProtocol.meter.max - window.mixerProtocol.meter.min); - } - - getTotalPeak = () => { - if (this.props.vuVal > this.totalPeak) { - this.totalPeak = this.props.vuVal; - } - return this.totalHeight()*this.totalPeak; - } - - getWindowPeak = () => { - if (this.props.vuVal > this.windowPeak || (Date.now() - this.windowLast) > this.WINDOW) { - this.windowPeak = this.props.vuVal; - this.windowLast = Date.now() - } - return this.totalHeight()*this.windowPeak - } - - calcLower = () => { - let val = this.props.vuVal; - if (val >= window.mixerProtocol.meter.test) { - val = window.mixerProtocol.meter.test; - } - return this.totalHeight()*val; - } - - calcMiddle = () => { - let val = this.props.vuVal; - if (val < window.mixerProtocol.meter.test) { - val = window.mixerProtocol.meter.test; - } else if (val >= window.mixerProtocol.meter.zero) { - val = window.mixerProtocol.meter.zero; - } - return this.totalHeight()*(val-window.mixerProtocol.meter.test)+1; - } - - calcUpper = () => { - let val = this.props.vuVal; - if (val < window.mixerProtocol.meter.zero) { - val = window.mixerProtocol.meter.zero; - } - return this.totalHeight()*(val-window.mixerProtocol.meter.zero)+1; - } - - setRef = (el: HTMLCanvasElement) => { - this.canvas = el; - - this.paintVuMeter(); - } - - resetTotalPeak = () => { - this.totalPeak = 0; - } - - paintVuMeter = () => { - if (!this.canvas) return - - const context = this.canvas.getContext("2d", { - antialias: false, - stencil: false, - preserveDrawingBuffer: true - }) as CanvasRenderingContext2D - - if (!context) return - - const range = (window.mixerProtocol.meter.max - window.mixerProtocol.meter.min) - context.clearRect(0, 0, this.canvas.clientWidth, this.canvas.clientHeight); - - // lower part - context.fillStyle = 'rgb(0, 122, 37)'; - context.fillRect(0, (this.totalHeight() - this.calcLower()), this.canvas.clientWidth, this.calcLower()); - - // middle part - context.fillStyle = 'rgb(53, 167, 0)'; - context.fillRect(0, (this.totalHeight() * (range - window.mixerProtocol.meter.test) - this.calcMiddle()), this.canvas.clientWidth, this.calcMiddle()); - - // upper part (too high/clip) - context.fillStyle = 'rgb(206, 0, 0)'; - context.fillRect(0, (this.totalHeight() * (range - window.mixerProtocol.meter.zero) - this.calcUpper()), this.canvas.clientWidth, this.calcUpper()); - - // windowed peak - const windowPeak = this.getWindowPeak(); - if (this.windowPeak < window.mixerProtocol.meter.zero) { - context.fillStyle = 'rgb(16, 56, 0)'; - } else { - context.fillStyle = 'rgb(100, 100, 100)'; - } - context.fillRect(0, (this.totalHeight() - windowPeak), this.canvas.clientWidth, 2); - - // absolute peak - if (this.totalPeak < window.mixerProtocol.meter.zero) { - context.fillStyle = 'rgb(64, 64, 64)'; - } else { - context.fillStyle = 'rgb(255, 0, 0)'; - } - context.fillRect(0, (this.totalHeight() - this.getTotalPeak()), this.canvas.clientWidth, 2); - } - - render() { - this.paintVuMeter() - - return ( -
    - - -
    - ) - } -} - -const mapStateToProps = (state: any, props: any): IVuMeterInjectedProps => { - return { - vuVal: state.faders[0].vuMeters[props.faderIndex].vuVal, - showSnaps: state.settings[0].showSnaps - } -} - -export default connect(mapStateToProps)(VuMeter); diff --git a/client/index.ejs b/client/index.ejs index 2478c7bf..14f3d849 100644 --- a/client/index.ejs +++ b/client/index.ejs @@ -4,6 +4,12 @@ SISYFOS INTELLIGENT AUDIO CONTROLLER +
    @@ -12,4 +18,4 @@
    - \ No newline at end of file + diff --git a/client/index.tsx b/client/index.tsx index af5762c9..b7d0face 100644 --- a/client/index.tsx +++ b/client/index.tsx @@ -1,51 +1,66 @@ -import React from 'react'; -import ReactDom from 'react-dom'; -import App from './components/App'; -import { socketClientHandlers } from './utils/SocketClientHandlers' -import io from 'socket.io-client' - -//Redux: -import { createStore } from 'redux'; -import { Provider as ReduxProvider} from 'react-redux'; -import indexReducer from '../server/reducers/indexReducer'; -import { SOCKET_GET_SNAPSHOT_LIST, SOCKET_GET_CCG_LIST } from '../server/constants/SOCKET_IO_DISPATCHERS'; - -declare global { - interface Window { - storeRedux: any - mixerProtocol: any - mixerProtocolPresets: any - mixerProtocolList: any - socketIoClient: any - snapshotFileList: string[] - ccgFileList: string[] - } -} - -// *** Uncomment to log Socket I/O: -// localStorage.debug = 'socket.io-client:socket'; - -const storeRedux = createStore( - indexReducer -); -window.storeRedux = storeRedux -window.socketIoClient = io() -window.socketIoClient.emit(SOCKET_GET_SNAPSHOT_LIST) -window.socketIoClient.emit(SOCKET_GET_CCG_LIST) - - -console.log('Setting up SocketIO connection') -socketClientHandlers() -window.socketIoClient.emit('get-store', 'update local store'); -window.socketIoClient.emit('get-settings', 'update local settings'); -window.socketIoClient.emit('get-mixerprotocol', 'get selected mixerprotocol') - - - -ReactDom.render( - - - - , - document.getElementById('root') -) +import React from 'react' +import ReactDom from 'react-dom' +import App from './src/components/App' +import { socketClientHandlers } from './src/utils/SocketClientHandlers' +import io from 'socket.io-client' + +//Redux: +import storeRedux from '../shared/src/reducers/store' +import { Provider as ReduxProvider } from 'react-redux' +import { + SOCKET_GET_SNAPSHOT_LIST, + SOCKET_GET_CCG_LIST, + SOCKET_GET_MIXER_PRESET_LIST, + SOCKET_GET_PAGES_LIST, +} from '../shared/src/constants/SOCKET_IO_DISPATCHERS' + +import { I18nextProvider } from 'react-i18next' +import i18n from './src/utils/i18n' +import { IMixerProtocol } from '../shared/src/constants/MixerProtocolInterface' + +declare global { + interface Window { + storeRedux: any + reduxState: any + mixerProtocol: IMixerProtocol + mixerProtocolPresets: any + mixerProtocolList: any + socketIoClient: any + socketIoVuClient: any + snapshotFileList: string[] + ccgFileList: string[] + mixerPresetList: string[] + } +} + +// *** Uncomment to log Socket I/O: +// localStorage.debug = 'socket.io-client:socket'; + +window.storeRedux = storeRedux + +//Subscribe to redux store: +window.reduxState = window.storeRedux.getState() +const unsubscribe = window.storeRedux.subscribe(() => { + window.reduxState = window.storeRedux.getState() +}) + +window.socketIoClient = io() +window.socketIoClient.emit(SOCKET_GET_SNAPSHOT_LIST) +window.socketIoClient.emit(SOCKET_GET_CCG_LIST) +window.socketIoClient.emit(SOCKET_GET_MIXER_PRESET_LIST) +window.socketIoClient.emit(SOCKET_GET_PAGES_LIST) + +console.log('Setting up SocketIO connection') +socketClientHandlers() +window.socketIoClient.emit('get-store', 'update local store') +window.socketIoClient.emit('get-settings', 'update local settings') +window.socketIoClient.emit('get-mixerprotocol', 'get selected mixerprotocol') + +ReactDom.render( + + + + + , + document.getElementById('root') +) diff --git a/client/package.json b/client/package.json new file mode 100644 index 00000000..e2131e1e --- /dev/null +++ b/client/package.json @@ -0,0 +1,42 @@ +{ + "name": "client", + "version": "0.0.0", + "license": "MIT", + "scripts": { + "build": "webpack --config webpack.config.js --mode production", + "watch": "webpack --config webpack.config.js --mode development --watch", + "test": "echo \"Everything is fine\"", + "test:watch": "echo \"Everything is fine and not watching\"" + }, + "devDependencies": { + "@types/node": "^18.16.0", + "@types/react-dom": "^18.2.4", + "@types/react-test-renderer": "^18.0.0", + "@babel/core": "^7.21.8", + "css-loader": "^6.7.3", + "html-webpack-plugin": "^5.5.1", + "react-test-renderer": "^18.2.0", + "style-loader": "^3.3.2", + "ts-loader": "^9.4.2", + "typescript": "^5.0.4", + "webpack": "^5.82.1", + "webpack-cli": "^5.1.1", + "classnames": "^2.3.2", + "i18next": "^20.6.1", + "i18next-browser-languagedetector": "^7.0.1", + "nouislider": "^15.7.0", + "nouislider-react": "^3.4.1", + "prop-types": "^15.8.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-draggable": "^4.4.5", + "react-i18next": "^12.2.2", + "react-redux": "^8.0.5", + "react-select": "^5.7.3", + "react-slider": "^2.0.4", + "reactjs-popup": "^2.0.5", + "redux": "^4.2.1", + "socket.io-client": "^4.6.2", + "webmidi": "^2.5.1" + } +} diff --git a/client/src/assets/css/App.css b/client/src/assets/css/App.css new file mode 100644 index 00000000..761cdbd0 --- /dev/null +++ b/client/src/assets/css/App.css @@ -0,0 +1,28 @@ +/* Main CSS file */ +body { + margin: 0; + padding: 0; + font-family: sans-serif; + background-color: black; + user-select: none; + overscroll-behavior: contain; +} + +.App { + position: relative; + text-align: center; +} + +.server-offline { + position: absolute; + top: 30vh; + left: 30vw; + margin-right: 30vw; + color: aliceblue; + background-color: rgba(163, 1, 1, 0.65); + font-size: 400%; + border-radius: 8px; + border-width: 4px; + border-color: rgba(144, 0, 0, 0.596); + z-index: 200; +} diff --git a/client/assets/css/CcgChannelSettings.css b/client/src/assets/css/CcgChannelSettings.css similarity index 100% rename from client/assets/css/CcgChannelSettings.css rename to client/src/assets/css/CcgChannelSettings.css diff --git a/client/src/assets/css/ChanStrip.css b/client/src/assets/css/ChanStrip.css new file mode 100644 index 00000000..8bab0bf9 --- /dev/null +++ b/client/src/assets/css/ChanStrip.css @@ -0,0 +1,253 @@ +.chan-strip-body { + position: relative; + top: 5px; + width: 500px; + height: 940px; + background-color: rgb(31, 31, 31); + border-color: rgb(70, 70, 70); + border-style: solid; + border-width: 4px; + border-radius: 8px; + text-align: left; + color: #fff; +} + +.chan-strip-body > .header { + margin-left: 40px; + margin-top: 10px; + margin-right: 80px; + /* width: 420px; */ + font-size: 240%; + color: #fff; + white-space: nowrap; +} + +.chan-strip-body > .parameters { + top: 5px; + left: 2px; + height: 900px; + overflow: auto; + text-align: center; + color: #fff; +} + +.chan-strip-body .parameters .horizontal { + display: flex; + justify-content: space-evenly; +} +.chan-strip-body .parameters .horizontal .item { +} +.chan-strip-body .parameters .horizontal .item .content { + display: flex; +} + +.parameters > .inp-comp-del-group { + display: flex; + top: 5px; + left: 2px; + margin-left: 5px; + overflow: auto; + text-align: center; + color: #fff; +} + +.inp-comp-del-group > .horizontal-space { + width: 40px; + height: 50px; +} + +.parameters > .eq-group, +.content > .eq-group { + display: flex; + top: 5px; + left: 2px; + margin-left: 90px; + overflow: auto; + text-align: center; + font-size: 14px; + color: #fff; +} +.content > .eq-group { + margin-left: 0; +} + +.eq-group > .horizontal-space { + width: 150px; + height: 50px; +} + +.eq > .group-text { + text-align: center; + line-height: 20px; + font-size: 110%; +} + +.zero-eq { + width: 63px; + height: 2px; + margin-left: -68px; + margin-right: 30px; + margin-top: 111px; +} + +.zero-comp { + width: 63px; + height: 2px; + margin-left: -68px; + margin-right: 30px; + margin-top: 81px; +} + +.zero-monitor { + width: 2px; + height: 20px; + margin-left: 10px; + margin-top: -150px; +} + +.parameters > .parameter-text, +.content > .parameter-text { + list-style-type: none; + text-align: center; + margin-top: 15px; + line-height: 10px; + font-size: 14px; +} + +.parameter-text > .parameter-mini-text, +.content > .parameter-mini-text { + list-style-type: none; + text-align: center; + margin-top: 5px; + line-height: 10px; + font-size: 80%; +} + +.inp-comp-del-group > .delayButtons { + width: 30px; + margin-top: 24px; + margin-left: 50px; +} +.content > .delayButtons { + width: 30px; + margin-top: 24px; + margin-left: 50px; +} + +.delayButtons > .delayTime { + outline: none; + -moz-outline: none; + color: white; + height: 45px; + width: 70px; + border-color: rgb(71, 71, 71); + background-color: rgb(53, 53, 53); + margin-left: -50px; + margin-top: 5px; + border-radius: 7px; +} + +.inp-comp-del-group > .input-buttons { + width: 30px; + margin-top: 24px; + margin-left: 50px; +} +.inp-comp-del-group .input-buttons.disabled { + visibility: hidden; +} +.content > .input-buttons { + width: 30px; + margin-top: 24px; + margin-left: 50px; +} +.content > .input-buttons.disabled { + visibility: hidden; +} + +.input-buttons > .input-select { + outline: none; + -moz-outline: none; + color: white; + height: 62px; + width: 70px; + border-color: rgb(71, 71, 71); + background-color: rgb(53, 53, 53); + margin-left: -50px; + margin-top: 5px; + border-radius: 7px; +} +.input-buttons > .input-select.active { + background-color: #2f475b; +} + +.parameters > .monitor-sends, +.content > .monitor-sends { + list-style-type: none; + display: flex; + text-align: center; + margin-top: 15px; + margin-left: 1px; + padding: 0px; + line-height: 10px; + font-size: 95%; +} + +.header > .close { + position: absolute; + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + border-radius: 20px; + color: #fff; + width: 50px; + height: 50px; + font-size: 30px; + /* margin-top: 5px; */ + right: 10px; +} + +.header > .button { + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + border-radius: 7px; + margin-left: 10px; + width: 80px; + height: 50px; + font-size: 12px; + line-height: 30px; + color: #fff; +} + +.chan-strip-fader { + width: 10px; + height: 190px; + margin-left: 35px; + margin-right: 30px; + margin-top: 10px; + border-width: 0px; + border-style: solid; + border-radius: 8px; + background-color: rgb(17, 17, 17); +} + +.chan-strip-thumb { + margin-left: -20px; + color: #3a3a3a; + font-size: 90%; + line-height: 50px; + width: 45px; + height: 49px; + border: 1px solid #c5c2c2; + border-radius: 8px; + background: linear-gradient( + to top, + #3a3a3a 0%, + #c2c2c2 20%, + hsl(0, 0%, 57%) 50%, + #00a 1px, + #919191 52%, + #c2c2c2 80%, + #3a3a3a 100% + ); +} diff --git a/client/src/assets/css/ChanStripEq.css b/client/src/assets/css/ChanStripEq.css new file mode 100644 index 00000000..8d258a7b --- /dev/null +++ b/client/src/assets/css/ChanStripEq.css @@ -0,0 +1,73 @@ +.eq-full { + justify-content: space-evenly; +} + +.eq-full > .eq-text { + display: flex; + justify-content: space-evenly; + top: 2vh; + left: 2vw; + width: 75vw; + height: 10vh; + margin-left: 1vw; + margin-top: 2vh; +} + +.eq-text-parameters { + max-width: 22vw; +} + +.eq-full > .eq-window { + top: 2vh; + left: 2vw; + margin-top: 3vh; + margin-left: 4vw; + height: 30vh; + width: 0vw; +} + +.eq-full > .eq-canvas { + position: absolute; + margin-left: -36.5vw; + margin-top: 5vh; + height: 30vh; + width: 72vw; +} + +.eq-window > .dot { + position: absolute; + font-size: 5vh; + height: 10vh; +} + +.chstrip-q { + width: 15vw; + height: 0.5vh; + margin-left: 5vw; + margin-right: 5vw; + margin-top: 1vh; + border-width: 0px; + border-style: solid; + border-radius: 8px; + background-color: rgb(17, 17, 17); +} +.chstrip-q-thumb { + margin-top: -2vh; + color: #3a3a3a; + font-size: 0.8vh; + width: 3vw; + height: 4vh; + line-height: 4vh; + border: 1px solid #c5c2c2; + border-radius: 8px; + background: linear-gradient( + to right, + #3a3a3a 0%, + #c2c2c2 20%, + hsl(0, 0%, 57%) 50%, + #00a 1px, + #919191 52%, + #c2c2c2 80%, + #3a3a3a 100% + ); +} diff --git a/client/src/assets/css/ChanStripFull.css b/client/src/assets/css/ChanStripFull.css new file mode 100644 index 00000000..20e422d9 --- /dev/null +++ b/client/src/assets/css/ChanStripFull.css @@ -0,0 +1,235 @@ +.chstrip-full-body { + justify-content: space-evenly; + position: fixed; + top: 5vh; + left: 5vw; + width: 90vw; + height: 90vh; + overflow: auto; + background-color: rgb(36, 36, 36); + border-color: rgb(149, 149, 149); + border-style: solid; + border-width: 4px; + border-radius: 8px; + text-align: left; + z-index: 2; + color: #fff; +} + +.ch-strip-full-header { + margin-left: 5vw; + margin-top: 1vh; + margin-right: 10vw; + /* width: 420px; */ + font-size: 3vh; + white-space: nowrap; +} + +.chstrip-full-parameters { + display: flex; + justify-content: left; + top: 2vh; + left: 2vw; + height: 30vh; + overflow: auto; + font-size: 1.5vh; + text-align: center; +} + +.chstrip-full-eq-window { + display: flex; + justify-content: space-evenly; + font-size: 1.5vh; + text-align: center; +} + +.chstrip-full-parameter-text { + list-style-type: none; + text-align: center; + margin-top: 2vh; + font-size: 1.5vh; +} + +.chstrip-full-content-group { + display: flex; + flex-direction: column; + margin-right: 2vw; +} + +.chstrip-full-content { + display: flex; + flex-direction: row; +} + +.chstrip-full-parameter-reduction { + list-style-type: none; + text-align: center; + margin-top: 2vh; + font-size: 1.5vh; + margin-left: 3vw; +} + +.chstrip-full-mini-text { + list-style-type: none; + text-align: center; + max-width: 9vw; + margin-top: 1vh; + font-size: 0.8vh; +} + +.chstrip-full-zero-comp { + width: 1vw; + height: 0.2vh; + margin-left: -6.5vw; + margin-top: 15vh; + font-size: 0.8vw; +} + +.chstrip-full-zero-monitor { + width: 1vw; + height: 0.2vh; + margin-left: 3.5vw; + margin-top: -12vh; +} + +.chstrip-full-parameter-text > .parameter-button-text { + list-style-type: none; + text-align: center; + margin-top: 2vh; + font-size: 1.2vh; +} + +.chstrip-full-parameter-text > .parameter-button { + margin-left: -8vw; + margin-top: 2vh; + outline: none; + -moz-outline: none; + margin-left: 3px; + margin-right: 3px; + color: white; + height: 4vh; + width: 4vw; + font-size: 1.2vh; + background-color: rgb(80, 80, 80); + border-radius: 7px; + border-color: rgb(99, 99, 99); +} + +.chstrip-full-delay-buttons { + margin-top: 3vh; + margin-left: 1vw; +} +.noDelayButtons { + margin-top: 24px; + min-height: 220px; +} + +.chstrip-full-delay-buttons > .delayTime { + outline: none; + -moz-outline: none; + color: white; + height: 5vh; + width: 4vw; + border-color: rgb(71, 71, 71); + background-color: rgb(53, 53, 53); + margin-left: 0vw; + margin-top: 1vh; + border-radius: 7px; +} + +.chstrip-full-content > .input-buttons { + width: 30px; + margin-top: 24px; + margin-left: 50px; +} +.chstrip-full-content > .input-buttons.disabled { + visibility: hidden; +} + +.input-buttons > .input-select { + outline: none; + -moz-outline: none; + color: white; + height: 62px; + width: 70px; + border-color: rgb(71, 71, 71); + background-color: rgb(53, 53, 53); + margin-left: -50px; + margin-top: 5px; + border-radius: 7px; +} +.input-buttons > .input-select.active { + background-color: #2f475b; +} + +.chstrip-full-monitor-sends { + list-style-type: none; + display: flex; + text-align: center; + margin-top: 2vh; + min-width: 20vw; +} + +.chstrip-full-monitor-text { + list-style-type: none; + text-align: center; + margin-top: 2vh; + font-size: 1.5vh; + margin-left: -5vw; +} + +.ch-strip-full-header > .close { + position: absolute; + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + border-radius: 20px; + color: #fff; + width: 5vh; + height: 5vh; + font-size: 2vw; + right: 3vw; +} + +.ch-strip-full-header > .button { + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + border-radius: 7px; + margin-left: 3vw; + width: 10vw; + height: 4vh; + font-size: 0.8vw; +} + +.chstrip-full-fader { + width: 0.5vw; + height: 15vh; + margin-left: 5vw; + margin-right: 5vw; + margin-top: 3vh; + border-width: 0px; + border-style: solid; + border-radius: 8px; + background-color: rgb(17, 17, 17); +} +.chstrip-full-thumb { + margin-left: -1.2vw; + color: #3a3a3a; + font-size: 1vh; + line-height: 4vh; + width: 3vw; + height: 4vh; + border: 1px solid #c5c2c2; + border-radius: 0.4vw; + background: linear-gradient( + to top, + #3a3a3a 0%, + #c2c2c2 20%, + hsl(0, 0%, 57%) 50%, + #00a 1px, + #919191 52%, + #c2c2c2 80%, + #3a3a3a 100% + ); +} diff --git a/client/assets/css/Channel.css b/client/src/assets/css/Channel.css similarity index 51% rename from client/assets/css/Channel.css rename to client/src/assets/css/Channel.css index 94911723..a22aaf4c 100644 --- a/client/assets/css/Channel.css +++ b/client/src/assets/css/Channel.css @@ -1,192 +1,280 @@ -.channel-body { - color: white; - background: linear-gradient(#2f2f2f 0px,#2f2f2f 790px, rgb(0, 0, 0) 1px, #2f2f2f 800px, #2f2f2f 100%); - margin: 4px; - border-radius: 7px; - width: 86px; - height: 950px; - position: relative; -} - -.channel-body.ignore-on { - background: linear-gradient(#575757 0px,#636363 790px, rgb(0, 0, 0) 1px, #636363 800px, #414141 100%); -} - -.channel-body.mute-on { - background: linear-gradient(#202020 0px,#202020 790px, rgb(0, 0, 0) 1px, #2f2f2f 800px, #2f2f2f 100%); -} - -.channel-gain-label { - color: #777777; - font-size: 0.8em; - margin-top: 10px; - text-align: center; -} - -.channel-pgm-button { - outline : none; - -moz-outline : none; - margin-left: 3px; - margin-right: 3px; - margin-top: 25px; - color: white; - height: 90px; - width: 80px; - font-size: 105%; - background-color: rgb(66, 27, 27); - border-radius: 7px; - border-color: rgb(99, 99, 99); -} - -.channel-pgm-button.on { - background-color: red; -} - -.channel-pgm-button.mute { - opacity: 0.3; - color: rgb(117, 117, 117); -} - - -.channel-vo-button { - outline : none; - -moz-outline : none; - margin-left: 3px; - margin-right: 3px; - margin-top: 5px; - color: white; - height: 90px; - width: 80px; - font-size: 105%; - background-color: rgb(66, 54, 27); - border-radius: 7px; - border-color: rgb(99, 99, 99); -} - - -.channel-vo-button.on { - background-color: rgb(207, 135, 1); -} - -.channel-vo-button.mute { - opacity: 0.3; - color: rgb(117, 117, 117); -} - -.channel-pst-button { - outline : none; - -moz-outline : none; - margin-left: 3px; - margin-right: 3px; - margin-top: 22px; - color: white; - height: 90px; - width: 80px; - font-size: 103%; - background-color: rgb(88, 88, 88); - border-radius: 7px; - border-color: rgb(99, 99, 99); - margin-bottom: 0; -} - -.channel-pst-button.on { - background-color: rgb(124, 0, 0); -} - -.channel-pst-button.vo { - background-color: rgb(163, 106, 0); -} - -.channel-mute-button { - outline : none; - -moz-outline : none; - margin-left: 3px; - margin-right: 3px; - margin-top: 5px; - color: rgb(109, 108, 108); - height: 50px; - width: 80px; - font-size: 90%; - background-color: rgb(44, 44, 44); - border-radius: 7px; - border-color: rgb(109, 108, 108); -} - - -.channel-mute-button.on { - background-color: rgb(168, 168, 168); - color: rgb(48, 48, 48); -} - -.channel-ignore-button { - outline : none; - -moz-outline : none; - margin-left: 3px; - margin-right: 3px; - margin-top: 5px; - color: rgb(109, 108, 108); - height: 50px; - width: 80px; - font-size: 90%; - background-color: rgb(44, 44, 44); - border-radius: 7px; - border-color: rgb(109, 108, 108); -} - - -.channel-ignore-button.on { - background-color: rgb(168, 168, 168); - color: rgb(1, 12, 114); -} - -@keyframes pfl-active-flash { - 0% { - box-shadow: 0 0 10px rgba(105, 140, 255, 1); - } - 50% { - box-shadow: 0 0 10px rgba(105, 140, 255, 1); - } - 50.0001% { - box-shadow: 0 0 10px rgba(105, 140, 255, 0); - } - 100% { - box-shadow: 0 0 10px rgba(105, 140, 255, 0); - } -} - -.channel-strip-button { - outline : none; - -moz-outline : none; - margin-left: 3px; - margin-top: 5px; - margin-right: 3px; - color: white; - height: 50px; - width: 80px; - font-size: 105%; - background-color: rgba(39, 39, 39, 0.308); - border-radius: 7px; - border-color: rgba(99, 99, 99, 0.301); -} - -.channel-volume-fader { - width: 10px; - height: 420px; - margin-left: 55px; - margin-top: 20px; - background-color: rgb(15, 15, 15); - border-color: rgba(0,0,0); - -} - - -:focus { - outline: 0; - } - -.channel-zero-indicator { - color: rgb(134, 134, 134); - position: absolute; - top: 214px; - left: 37px; -} \ No newline at end of file +.channel-body { + color: white; + background: linear-gradient( + #2f2f2f 0px, + #2f2f2f 790px, + rgb(0, 0, 0) 1px, + #2f2f2f 800px, + #2f2f2f 100% + ); + margin: 4px; + border-radius: 7px; + height: 950px; + position: relative; + touch-action: none; + display: flex; + flex-direction: column; + align-items: center; +} +.channel-body > .channel-props { + display: flex; + flex-direction: column; +} +.channel-body > .channel-props, +.channel-body > .out-control, +.channel-body > .channel-control { + flex-grow: 0; +} +.channel-body > .fader { + flex-grow: 1; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} +.channel-body > .out-control { + padding-bottom: 5px; + display: flex; + flex-direction: column; +} +.channel-body > .channel-control { + height: 160px; + display: flex; + flex-direction: column-reverse; +} + +.channel-body.ignore-on { + background: linear-gradient( + #575757 0px, + #636363 790px, + rgb(0, 0, 0) 1px, + #636363 800px, + #414141 100% + ); +} + +.channel-body.mute-on { + background: linear-gradient( + #202020 0px, + #202020 790px, + rgb(0, 0, 0) 1px, + #2f2f2f 800px, + #2f2f2f 100% + ); +} + +.channel-gain-label { + color: #777777; + font-size: 0.8em; + margin-top: 10px; + text-align: center; +} + +.channel-pgm-button { + outline: none; + -moz-outline: none; + margin-left: 3px; + margin-right: 3px; + margin-top: 3px; + color: white; + height: 90px; + width: 80px; + font-size: 105%; + background-color: rgb(66, 27, 27); + border-radius: 7px; + border-color: rgb(99, 99, 99); +} + +.channel-pgm-button.on { + background-color: red; +} + +.channel-pgm-button.mute { + opacity: 0.3; + color: rgb(117, 117, 117); +} + +.channel-vo-button { + outline: none; + -moz-outline: none; + margin-left: 3px; + margin-right: 3px; + margin-top: 3px; + color: white; + height: 90px; + width: 80px; + font-size: 105%; + background-color: rgb(66, 54, 27); + border-radius: 7px; + border-color: rgb(99, 99, 99); +} + +.channel-vo-button.on { + background-color: rgb(207, 135, 1); +} + +.channel-vo-button.mute { + opacity: 0.3; + color: rgb(117, 117, 117); +} + +.channel-pst-button { + outline: none; + -moz-outline: none; + margin-left: 3px; + margin-right: 3px; + margin-top: 3px; + color: white; + height: 90px; + width: 80px; + font-size: 103%; + background-color: rgb(88, 88, 88); + border-radius: 7px; + border-color: rgb(99, 99, 99); + margin-bottom: 0; +} + +.channel-pst-button.on { + background-color: rgb(34, 135, 20); +} + +.channel-pst-button.vo { + background-color: rgb(163, 106, 0); +} + +.channel-mute-button, +.channel-amix-button { + outline: none; + -moz-outline: none; + margin-left: 3px; + margin-right: 3px; + margin-top: 5px; + color: rgb(109, 108, 108); + height: 50px; + width: 80px; + font-size: 90%; + background-color: rgb(44, 44, 44); + border-radius: 7px; + border-color: rgb(109, 108, 108); +} + +.channel-mute-button.on { + background-color: rgb(168, 168, 168); + color: rgb(48, 48, 48); +} + +.channel-amix-button.on { + background-color: rgb(78, 59, 97); + color: rgb(255, 255, 255); +} +.channel-amix-button.disabled { + visibility: hidden; +} + +.channel-ignore-button { + outline: none; + -moz-outline: none; + margin-left: 3px; + margin-right: 3px; + margin-top: 5px; + color: rgb(109, 108, 108); + height: 50px; + width: 80px; + font-size: 90%; + background-color: rgb(44, 44, 44); + border-radius: 7px; + border-color: rgb(109, 108, 108); +} + +.channel-ignore-button.on { + background-color: rgb(168, 168, 168); + color: rgb(1, 12, 114); +} + +@keyframes pfl-active-flash { + 0% { + box-shadow: 0 0 10px rgba(105, 140, 255, 1); + } + 50% { + box-shadow: 0 0 10px rgba(105, 140, 255, 1); + } + 50.0001% { + box-shadow: 0 0 10px rgba(105, 140, 255, 0); + } + 100% { + box-shadow: 0 0 10px rgba(105, 140, 255, 0); + } +} + +.channel-strip-button { + outline: none; + -moz-outline: none; + margin-left: 3px; + margin-top: 5px; + margin-right: 3px; + color: white; + height: 50px; + width: 80px; + font-size: 105%; + background-color: rgba(39, 39, 39, 0.308); + border-radius: 7px; + border-color: rgba(99, 99, 99, 0.301); +} +.channel-strip-button.active { + background-color: #2f475b; +} + +.channel-volume-fader { + width: 10px; + height: calc(100% - 60px); + margin: 30px 20px; + background-color: rgb(15, 15, 15); + border-color: rgba(0, 0, 0); +} + +/* .channel-volume-fader::before, +.channel-volume-fader::after { + content: '__'; + position: absolute; + color: rgb(134, 134, 134); + top: 92px; +} +.channel-volume-fader::before { + left: 9px; +} +.channel-volume-fader::after { + right: 9px; +} */ + +:focus { + outline: 0; +} + +.channel-zero-indicator { + color: rgb(134, 134, 134); + position: absolute; + top: 206px; + left: 37px; +} + +.channel-zero-button { + background-color: rgba(134, 134, 134, 0.048); + color: #20202000; + border-color: #20202000; + position: absolute; + top: 222px; + right: 5px; + height: 40px; + width: 80%; +} + +.not-found::after { + content: ' '; + z-index: 1; + position: absolute; + background-color: black; + width: 86px; + height: 950px; + opacity: 0.65; + top: 0; +} diff --git a/client/assets/css/ChannelMonitorOptions.css b/client/src/assets/css/ChannelMonitorOptions.css similarity index 100% rename from client/assets/css/ChannelMonitorOptions.css rename to client/src/assets/css/ChannelMonitorOptions.css diff --git a/client/src/assets/css/ChannelRouteSettings.css b/client/src/assets/css/ChannelRouteSettings.css new file mode 100644 index 00000000..dcf3aab4 --- /dev/null +++ b/client/src/assets/css/ChannelRouteSettings.css @@ -0,0 +1,81 @@ +.channel-route-body { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 400px; + overflow: auto; + max-height: 90vh; + background-color: rgb(31, 31, 31); + border-color: rgb(124, 124, 124); + border-style: solid; + border-width: 4px; + text-align: left; + z-index: 2; + + color: #fff; +} + +.channel-route-body > h2 { + border-bottom: 1px solid #999; + margin: 0; + padding: 10px 0; + line-height: 50px; + text-align: center; +} + +.channel-route-mixer-name { + font-size: 150%; + border-bottom: 1px solid #999; + margin: 0; + padding: 10px 0; + line-height: 50px; + text-align: center; +} + +.channel-route-text { + color: dimgray; + margin: 0; + margin-left: 40px; + padding: 0px 0; + line-height: 20px; + text-align: left; + font-size: 110%; +} + +.channel-route-text.checked { + font-weight: bold; + color: white; +} + +.channel-route-body > .close { + position: absolute; + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + border-radius: 100%; + display: block; + color: #fff; + width: 50px; + height: 50px; + font-size: 30px; + line-height: 50px; + top: -5px; + right: 9px; +} + +.channel-route-body > button { + line-height: 10px; + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + margin-right: 10px; + margin-top: 15px; + margin-bottom: 15px; + margin-left: 10px; + border-radius: 7px; + color: #fff; + width: 34%; + font-size: 10px; + line-height: 50px; +} diff --git a/client/src/assets/css/Channels.css b/client/src/assets/css/Channels.css new file mode 100644 index 00000000..26797266 --- /dev/null +++ b/client/src/assets/css/Channels.css @@ -0,0 +1,135 @@ +.channels-body { + display: flex; + flex-direction: row; + background-color: black; + min-height: 760px; +} + +.channels-body > .channels-body-inner { + display: flex; + flex-direction: row; + flex-grow: 2; + overflow-x: auto; + height: calc(100vh); +} + +.channels-body > .closedChanStrip { + /* margin-left: -630px; */ + transition: transform 300ms; + position: absolute; + z-index: 2; + transform: translateX(-100%); +} + +.channels-body > .openChanStrip { + /* margin-left: 0px; + transition: margin 800ms; */ + transition: transform 300ms; + transform: unset; +} + +.button { + outline: none; + -moz-outline: none; + color: white; + height: 90px; + width: 90px; + border-color: rgb(71, 71, 71); + background-color: rgb(53, 53, 53); + margin-left: 5px; + margin-right: 4px; + margin-top: 10px; + border-radius: 7px; +} +.button.half { + height: 60px; +} +.button.active { + background-color: #2f475b; +} + +.button-all-manual.all { + background-color: #af39b9; +} +.button-all-manual.any { + border-color: #af39b9; +} + +.channels-mix-body { + display: flex; + flex-direction: column; + + width: 100px; + min-height: 950px; + max-height: calc(100vh - 10px); + color: white; + background: linear-gradient( + #2f2f2f 0px, + #2f2f2f 790px, + rgb(0, 0, 0) 1px, + #2f2f2f 800px, + #2f2f2f 100% + ); + margin: 4px; + border-radius: 9px; + border-color: rgb(80, 80, 80); + border-style: solid; + border-width: 1px; +} +.channels-mix-body > .mid { + flex-grow: 2; + display: flex; + flex-direction: column; + justify-content: center; +} +.channels-mix-body > .bot { + overflow-y: auto; +} + +.channels-show-mixer-online { + background-color: rgb(219, 1, 1); +} + +.channels-show-mixer-online.connected { + background-color: rgb(9, 107, 0); +} + +.channels-show-settings-button { +} +.channels-show-settings-button.active { + background-color: #2f475b; +} + +.channels-show-storage-button { +} + +.channels-mix-button { + background-color: rgb(65, 65, 65); +} + +.channels-clear-button { + background-color: rgb(19, 19, 19); +} + +.channels-snap-mix-body { + /* margin-top: 58px; */ +} + +.channels-snap-mix-line { + margin-top: 4px; + background-color: #2b2b2b; +} + +.channels-snap-mix-button { + background-color: rgb(199, 202, 0); + color: rgb(44, 44, 44); + margin-left: 20px; + height: 25px; + width: 60px; + border-color: rgb(99, 99, 99); + white-space: nowrap; +} + +.channels-snap-mix-line:last-of-type { + margin-bottom: 51px; +} diff --git a/client/src/assets/css/LabelSettings.css b/client/src/assets/css/LabelSettings.css new file mode 100644 index 00000000..40e95d28 --- /dev/null +++ b/client/src/assets/css/LabelSettings.css @@ -0,0 +1,102 @@ +.label-settings-body { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 600px; + overflow: auto; + max-height: 90vh; + background-color: rgb(31, 31, 31); + border-color: rgb(124, 124, 124); + border-style: solid; + border-width: 4px; + text-align: center; + align-items: center; + z-index: 2; + + color: #fff; +} + +.label-settings-body > h2 { + border-bottom: 1px solid #999; + margin: 0; + padding: 10px 0; + line-height: 50px; + text-align: center; +} + +.pages-settings-mixer-name { + font-size: 150%; + border-bottom: 1px solid #999; + margin: 0; + padding: 10px 0; + line-height: 50px; + text-align: center; +} + +.pages-settings-text { + color: dimgray; + margin: 0; + margin-left: 40px; + padding: 0px 0; + line-height: 20px; + text-align: right; + font-size: 110%; +} + +.pages-settings-tick { + color: dimgray; + margin: 0; + margin-right: 70px; + padding: 0px 0; + line-height: 20px; + text-align: right; + align-content: right; + font-size: 110%; +} + +.pages-settings.checked { + font-weight: bold; + color: white; +} + +.label-settings-body > .close { + position: absolute; + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + border-radius: 100%; + display: block; + color: #fff; + width: 50px; + height: 50px; + font-size: 30px; + line-height: 50px; + top: -5px; + right: 9px; +} + +.label-settings-body > .button { + line-height: 20px; + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(58, 3, 3); + margin-top: 15px; + margin-bottom: 15px; + border-radius: 7px; + color: #fff; + width: 34%; + height: 50px; + font-size: 10px; +} + +.label-settings-body > .inputfield { + line-height: 40px; + outline: none; + margin-top: 45px; + border-radius: 7px; + color: #fff; + width: 34%; + height: 50px; + font-size: 18px; +} diff --git a/client/src/assets/css/MicTally.css b/client/src/assets/css/MicTally.css new file mode 100644 index 00000000..7111bc37 --- /dev/null +++ b/client/src/assets/css/MicTally.css @@ -0,0 +1,130 @@ +body.v-mic-tally { + background: transparent; + min-height: 100%; +} + +.mic-tally-view { + position: relative; + color: white; + width: 100%; + height: 100%; +} + +.mic-tally-list { + display: flex; + list-style: none; + align-items: stretch; + flex-wrap: wrap; + padding: 0; + margin: 0; + opacity: 0; + transition: opacity 0.2s; +} + +.mic-tally-list.active { + opacity: 1; +} + +.c-mic-tally { + margin: 8px; + flex: 1 1 80px; + min-width: 80px; + text-align: center; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} +.c-mic-tally:not(:first-child) { + margin-left: 8px; +} +.c-mic-tally__status { + display: flex; + justify-content: center; + align-items: center; + font-weight: bold; + border-radius: 100%; + margin: 0 auto; + background-color: #444444; + border: 2px solid #888888; + width: 60px; + height: 60px; + cursor: pointer; +} + +.c-mic-tally__status:active:not(.muted) { + background-color: #888888; +} + +.c-mic-tally__status.on { + color: #c40000; + background-color: #ffaaaa; + border-color: #c40000; + font-size: 1em; +} + +.c-mic-tally__status.on:active { + background-color: #c40000; + color: white; +} + +.c-mic-tally__status.muted { + cursor: not-allowed; + background-color: transparent; + border-color: #444444; +} + +.c-mic-tally__label { + display: block; + color: white; + font-weight: bold; + margin-top: 6px; + font-size: 0.9em; +} +.c-mic-tally__toggle-prompt { + display: none; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + align-items: center; + justify-content: center; + z-index: 10000; +} +.c-mic-tally__toggle-prompt.active { + display: flex; +} + +.c-mic-tally__toggle-prompt__content { + flex: 1; + text-align: center; + font-size: 18px; + font-weight: bold; +} +.c-mic-tally__toggle-prompt__actions { + display: flex; +} + +.c-mic-tally__toggle-prompt__actions button { + flex: 1; + outline: none; + -moz-outline: none; + padding: 12px; + margin: 8px; + border: none; + border-radius: 8px; + font-size: 16px; + font-weight: bold; + color: white; + background-color: #c40000; + cursor: pointer; + transition: background-color 0.2s, color 0.2s; +} +.c-mic-tally__toggle-prompt__actions button.cancel { + background-color: rgb(66, 27, 27); +} +.c-mic-tally__toggle-prompt__actions button:hover, +.c-mic-tally__toggle-prompt__actions button:active { + background-color: #ffaaaa; + color: rgb(66, 27, 27); +} diff --git a/client/src/assets/css/MiniChanStrip.css b/client/src/assets/css/MiniChanStrip.css new file mode 100644 index 00000000..8be11526 --- /dev/null +++ b/client/src/assets/css/MiniChanStrip.css @@ -0,0 +1,136 @@ +.monitor-chan-strip-body { + position: absolute; + top: 2px; + left: 100px; + width: 620px; + height: 280px; + background-color: rgb(31, 31, 31); + border-color: rgb(70, 70, 70); + border-style: solid; + border-width: 4px; + border-radius: 8px; + text-align: left; + color: #fff; +} + +.monitor-chan-strip-body > .header { + margin-left: 40px; + margin-top: 10px; + width: 420px; + font-size: 240%; + color: #fff; +} + +.monitor-chan-strip-body > .parameters { + margin-top: 5px; + top: 5px; + left: 2px; + height: 900px; + overflow: auto; + text-align: center; + color: #fff; +} + +.parameters > .parameter-group { + display: flex; + top: 5px; + left: 2px; + margin-left: 90px; + overflow: auto; + text-align: center; + color: #fff; +} + +.parameter-group > .horizontal-space { + width: 150px; + height: 50px; +} + +.parameters > .group-text { + text-align: center; + line-height: 20px; + font-size: 110%; +} + +.zero-monitor { + width: 2px; + height: 20px; + margin-left: 10px; + margin-top: -150px; +} + +.parameters > .parameter-text { + list-style-type: none; + text-align: center; + margin-top: 15px; + line-height: 10px; + font-size: 100%; +} + +.parameters > .monitor-sends { + list-style-type: none; + display: flex; + text-align: center; + margin-top: 15px; + margin-left: 1px; + padding: 0px; + line-height: 10px; + font-size: 95%; +} + +.monitor-chan-strip-body .header > .close { + position: fixed; + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + border-radius: 20px; + color: #fff; + width: 50px; + height: 50px; + font-size: 30px; + margin-top: 5px; + left: 550px; +} + +.header > button { + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + border-radius: 7px; + margin-left: 10px; + margin-top: 5px; + width: 180px; + font-size: 12px; + line-height: 40px; + color: #fff; +} + +.monitor-chan-strip-fader { + width: 10px; + height: 200px; + margin-left: 35px; + margin-right: 30px; + margin-top: 10px; + border-width: 0px; + border-style: solid; + border-radius: 8px; + background-color: rgb(17, 17, 17); +} + +.monitor-chan-strip-thumb { + margin-left: -20px; + width: 45px; + height: 49px; + border: 1px solid #c5c2c2; + border-radius: 8px; + background: linear-gradient( + to top, + #3a3a3a 0%, + #c2c2c2 20%, + hsl(0, 0%, 57%) 50%, + #00a 1px, + #919191 52%, + #c2c2c2 80%, + #3a3a3a 100% + ); +} diff --git a/client/src/assets/css/MiniChannel.css b/client/src/assets/css/MiniChannel.css new file mode 100644 index 00000000..8b049145 --- /dev/null +++ b/client/src/assets/css/MiniChannel.css @@ -0,0 +1,30 @@ +.monitor-channel-body { + color: white; + background: linear-gradient(#2f2f2f 0px,#2f2f2f 790px, rgb(0, 0, 0) 1px, #2f2f2f 800px, #2f2f2f 100%); + margin: 4px; + border-radius: 7px; + width: 86px; + height: 86px; + position: relative; +} + +.monitor-channel-strip-button { + outline : none; + -moz-outline : none; + margin-left: 3px; + margin-top: 5px; + margin-right: 3px; + color: white; + height: 80px; + width: 80px; + font-size: 105%; + background-color: rgba(39, 39, 39, 0.308); + border-radius: 7px; + border-color: rgba(77, 77, 77, 0.301); +} + +.monitor-channel-strip-button.on { + background-color: rgb(146, 146, 146); + border-color: rgba(102, 102, 102, 0.301); + +} diff --git a/client/src/assets/css/MiniChannels.css b/client/src/assets/css/MiniChannels.css new file mode 100644 index 00000000..0b66fe62 --- /dev/null +++ b/client/src/assets/css/MiniChannels.css @@ -0,0 +1,17 @@ +.mini-channels-body { + display: flex; + flex-direction: column; + background-color: black; + height: 400px; + width: 100px; +} + +.mini-channels-body > .closedChanStrip { + margin-left: 100px; + transition: margin 300ms; +} + +.mini-channels-body > .openChanStrip { + margin-left: 100px; + transition: margin 800ms; +} \ No newline at end of file diff --git a/client/src/assets/css/NoUiSlider.css b/client/src/assets/css/NoUiSlider.css new file mode 100644 index 00000000..93447ce3 --- /dev/null +++ b/client/src/assets/css/NoUiSlider.css @@ -0,0 +1,366 @@ +/*! nouislider - 14.1.1 - 12/15/2019 */ +/* Functional styling; + * These styles are required for noUiSlider to function. + * You don't need to change these rules to apply your design. + */ +.noUi-target, +.noUi-target * { + -webkit-touch-callout: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + -webkit-user-select: none; + -ms-touch-action: none; + touch-action: none; + -ms-user-select: none; + -moz-user-select: none; + user-select: none; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.noUi-target { + position: relative; +} +.noUi-base, +.noUi-connects { + width: 100%; + height: 100%; + position: relative; + z-index: 1; +} +/* Wrapper for all connect elements. + */ +.noUi-connects { + overflow: hidden; + z-index: 0; +} +.noUi-connect, +.noUi-origin { + will-change: transform; + position: absolute; + z-index: 1; + top: 0; + right: 0; + -ms-transform-origin: 0 0; + -webkit-transform-origin: 0 0; + -webkit-transform-style: preserve-3d; + transform-origin: 0 0; + transform-style: flat; +} +.noUi-connect { + height: 100%; + width: 100%; +} +.noUi-origin { + height: 97%; + width: 100%; +} +/* Offset direction + */ +.noUi-txt-dir-rtl.noUi-horizontal .noUi-origin { + left: 0; + right: auto; +} +/* Give origins 0 height/width so they don't interfere with clicking the + * connect elements. + */ +.noUi-vertical .noUi-origin { + width: 0; +} +.noUi-horizontal .noUi-origin { + height: 0; +} +.noUi-handle { + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + position: absolute; +} +.noUi-touch-area { + height: 100%; + width: 100%; +} +.noUi-state-tap .noUi-connect, +.noUi-state-tap .noUi-origin { + -webkit-transition: transform 0.3s; + transition: transform 0.3s; +} +.noUi-state-drag * { + cursor: inherit !important; +} +/* Slider size and handle placement; + */ +.noUi-horizontal { + height: 18px; +} +.noUi-horizontal .noUi-handle { + width: 34px; + height: 28px; + right: -17px; + top: -6px; +} +.noUi-vertical { + width: 18px; +} +.noUi-vertical .noUi-handle { + width: 49px; + height: 75px; + right: -20px; + top: -38px; +} +.noUi-txt-dir-rtl.noUi-horizontal .noUi-handle { + left: -17px; + right: auto; +} +/* Styling; + * Giving the connect element a border radius causes issues with using transform: scale + */ +.noUi-target { + background: #fafafa; + border-radius: 4px; + border: 1px solid #d3d3d3; + box-shadow: inset 0 1px 1px #f0f0f0, 0 3px 6px -5px #bbb; +} +.noUi-connects { + border-radius: 3px; +} +.noUi-connect { + background: #3fb8af; +} +/* Handles and cursors; + */ +.noUi-draggable { + cursor: ew-resize; +} +.noUi-vertical .noUi-draggable { + cursor: ns-resize; +} +.noUi-handle { + border: 1px solid #c5c2c2; + border-radius: 8px; + background: linear-gradient( + to top, + #3a3a3a 0%, + #c2c2c2 20%, + hsl(0, 0%, 57%) 50%, + #00a 1px, + #919191 52%, + #c2c2c2 80%, + #3a3a3a 100% + ); + cursor: default; +} + +.pgm-on .noUi-handle { + border: 1px solid rgb(253, 60, 60); + background: linear-gradient( + to top, + #3a1d1d 0%, + #c04d4d 20%, + #811919 50%, + #00a 1px, + #8a2626 52%, + #bd5151 80%, + #411f1f 100% + ); +} + +.vo-on .noUi-handle { + border: 1px solid rgb(252, 255, 86); + background: linear-gradient( + to top, + #353006 0%, + #c59327 20%, + #856b14 50%, + #00a 1px, + #866724 52%, + #cca22d 80%, + #463b0a 100% + ); +} + +.mute-on .noUi-handle { + border: 1px solid rgb(58, 58, 58); + background: linear-gradient( + to top, + #111111 0%, + #252525 20%, + #2b2b2b 50%, + rgb(56, 56, 56) 1px, + #292929 52%, + #222222 80%, + #222222 100% + ); +} + +.noUi-active { + box-shadow: inset 0 0 1px #fff, inset 0 1px 7px #ddd, 0 3px 6px -3px #bbb; +} +/* Handle stripes; + */ +.noUi-handle:after { + content: ''; + display: block; + position: absolute; + height: 14px; + width: 1px; + background: rgba(0, 0, 0, 0); + left: 14px; + top: 6px; +} +.noUi-handle:after { + left: 17px; +} +.noUi-vertical .noUi-handle:before, +.noUi-vertical .noUi-handle:after { + width: 14px; + height: 1px; + left: 6px; + top: 14px; +} +.noUi-vertical .noUi-handle:after { + top: 17px; +} +/* Disabled state; + */ +[disabled] .noUi-connect { + background: #b8b8b8; +} +[disabled].noUi-target, +[disabled].noUi-handle, +[disabled] .noUi-handle { + cursor: not-allowed; +} +/* Base; + * + */ +.noUi-pips, +.noUi-pips * { + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.noUi-pips { + position: absolute; + color: #999; +} +/* Values; + * + */ +.noUi-value { + position: absolute; + white-space: nowrap; + text-align: center; +} +.noUi-value-sub { + color: #ccc; + font-size: 10px; +} +/* Markings; + * + */ +.noUi-marker { + position: absolute; + background: #ccc; +} +.noUi-marker-sub { + background: #aaa; +} +.noUi-marker-large { + background: #aaa; +} +/* Horizontal layout; + * + */ +.noUi-pips-horizontal { + padding: 10px 0; + height: 80px; + top: 100%; + left: 0; + width: 100%; +} +.noUi-value-horizontal { + -webkit-transform: translate(-50%, 50%); + transform: translate(-50%, 50%); +} +.noUi-rtl .noUi-value-horizontal { + -webkit-transform: translate(50%, 50%); + transform: translate(50%, 50%); +} +.noUi-marker-horizontal.noUi-marker { + margin-left: -1px; + width: 2px; + height: 5px; +} +.noUi-marker-horizontal.noUi-marker-sub { + height: 10px; +} +.noUi-marker-horizontal.noUi-marker-large { + height: 15px; +} +/* Vertical layout; + * + */ +.noUi-pips-vertical { + padding: 0 10px; + height: 100%; + top: 0px; + left: 0%; +} +.noUi-value-vertical { + -webkit-transform: translate(0, -50%); + transform: translate(0, -100%); + padding-left: 0px; + font-size: 10px; +} +.noUi-rtl .noUi-value-vertical { + -webkit-transform: translate(0, 50%); + transform: translate(0, 100%); +} +.noUi-marker-vertical.noUi-marker { + width: 0px; + height: 2px; + margin-top: -1px; +} +.noUi-marker-vertical.noUi-marker-sub { + width: 10px; + height: 1px; +} +.noUi-marker-vertical.noUi-marker-sub::before { + content: ' '; + width: 10px; + height: 1px; + position: absolute; + background: #aaa; + left: -22px; +} +.noUi-marker-vertical.noUi-marker-large { + width: 15px; +} +.noUi-marker-vertical.noUi-marker-large::before { + content: ' '; + width: 15px; + height: 2px; + position: absolute; + background: #aaa; + left: -27px; +} +.noUi-tooltip { + display: block; + position: absolute; + border: 1px solid #d9d9d9; + border-radius: 3px; + background: #fff; + color: #000; + padding: 5px; + text-align: center; + white-space: nowrap; +} +.noUi-horizontal .noUi-tooltip { + -webkit-transform: translate(-50%, 0); + transform: translate(-50%, 0); + left: 50%; + bottom: 120%; +} +.noUi-vertical .noUi-tooltip { + -webkit-transform: translate(0, -50%); + transform: translate(0, -50%); + top: 50%; + right: 120%; +} diff --git a/client/src/assets/css/PagesSettings.css b/client/src/assets/css/PagesSettings.css new file mode 100644 index 00000000..ad0d988d --- /dev/null +++ b/client/src/assets/css/PagesSettings.css @@ -0,0 +1,103 @@ +.pages-settings-body { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 400px; + overflow: auto; + max-height: 90vh; + background-color: rgb(31, 31, 31); + border-color: rgb(124, 124, 124); + border-style: solid; + border-width: 4px; + text-align: center; + align-items: center; + z-index: 2; + + color: #fff; +} + +.pages-settings-body > h2 { + border-bottom: 1px solid #999; + margin: 0; + padding: 10px 0; + line-height: 50px; + text-align: center; +} + +.pages-settings-mixer-name { + font-size: 150%; + border-bottom: 1px solid #999; + margin: 0; + padding: 10px 0; + line-height: 50px; + text-align: center; +} + +.pages-settings-text { + color: dimgray; + margin: 0; + margin-left: 40px; + padding: 0px 0; + line-height: 20px; + text-align: right; + font-size: 110%; +} + +.pages-settings-tick { + color: dimgray; + margin: 0; + margin-right: 70px; + padding: 0px 0; + line-height: 20px; + text-align: right; + align-content: right; + font-size: 110%; +} + +.pages-settings.checked { + font-weight: bold; + color: white; +} + +.pages-settings-body > .close { + position: absolute; + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(27, 27, 27); + border-radius: 100%; + display: block; + color: #fff; + width: 50px; + height: 50px; + font-size: 30px; + line-height: 50px; + top: -5px; + right: 9px; +} + +.pages-settings-body > .button { + line-height: 20px; + outline: none; + border-color: rgb(99, 99, 99); + background-color: rgb(58, 3, 3); + margin-top: 15px; + margin-bottom: 15px; + margin-left: 130px; + border-radius: 7px; + color: #fff; + width: 34%; + height: 50px; + font-size: 10px; +} + +.pages-settings-body > .inputfield { + line-height: 40px; + outline: none; + margin-top: 45px; + border-radius: 7px; + color: #fff; + width: 34%; + height: 50px; + font-size: 18px; +} diff --git a/client/src/assets/css/ReductionMeter.css b/client/src/assets/css/ReductionMeter.css new file mode 100644 index 00000000..42b12413 --- /dev/null +++ b/client/src/assets/css/ReductionMeter.css @@ -0,0 +1,47 @@ +.reductionmeter-body { + top: 0.8vh; + width: 24px; + margin-top: 15px; + margin-left: 5px; + background-color: black; + border-radius: 7px; + font-size: 14px; +} + +.reductionmeter-canvas { + width: 10px; + margin-left: -5px; + bottom: 0px; + height: 240x; +} + +.reductionmeter-lower-part { + width: 10px; + margin-left: 10px; + background-color: rgb(0, 122, 37); +} +.reductionmeter-middle-part { + width: 10px; + margin-left: 10px; + background-color: rgb(53, 167, 0); +} +.reductionmeter-upper-part { + width: 10px; + margin-left: 10px; + background-color: rgb(206, 0, 0); +} + +.reduction-6db { + color: #445f4a; + width: 63px; + height: 2px; + margin-left: -6px; + margin-top: -105px; +} +.reduction-12db { + color: #5c3939; + width: 63px; + height: 2px; + margin-left: 2px; + margin-top: 50px; +} diff --git a/client/assets/css/RoutingStorage.css b/client/src/assets/css/RoutingStorage.css similarity index 100% rename from client/assets/css/RoutingStorage.css rename to client/src/assets/css/RoutingStorage.css diff --git a/client/assets/css/Settings.css b/client/src/assets/css/Settings.css similarity index 100% rename from client/assets/css/Settings.css rename to client/src/assets/css/Settings.css diff --git a/client/assets/css/VuMeter.css b/client/src/assets/css/VuMeter.css similarity index 84% rename from client/assets/css/VuMeter.css rename to client/src/assets/css/VuMeter.css index def13ce2..9bb419b3 100644 --- a/client/assets/css/VuMeter.css +++ b/client/src/assets/css/VuMeter.css @@ -1,37 +1,35 @@ -.vumeter-body { - position: absolute; - top: 110px; - width: 24px; - margin-top: 15px; - margin-left: 5px; - background-color: black; - border-radius: 7px; - height: 430px; -} - -.vumeter-canvas { - position: absolute; - width: 10px; - margin-left: 6px; - bottom: 0; - height: 100%; -} - -.vumeter-lower-part { - position: absolute; - width: 10px; - margin-left: 10px; - background-color: rgb(0, 122, 37); -} -.vumeter-middle-part { - position: absolute; - width: 10px; - margin-left: 10px; - background-color: rgb(53, 167, 0); -} -.vumeter-upper-part { - position: absolute; - width: 10px; - margin-left: 10px; - background-color: rgb(206, 0, 0); -} +.vumeter-body { + width: 24px; + margin-left: 2px; + margin-right: 4px; + background-color: black; + border-radius: 7px; + height: 430px; +} + +.vumeter-canvas { + width: 10px; + margin-left: 6px; + bottom: 0; + height: 100%; + margin-top: 50%; +} + +.vumeter-lower-part { + position: absolute; + width: 10px; + margin-left: 10px; + background-color: rgb(0, 122, 37); +} +.vumeter-middle-part { + position: absolute; + width: 10px; + margin-left: 10px; + background-color: rgb(53, 167, 0); +} +.vumeter-upper-part { + position: absolute; + width: 10px; + margin-left: 10px; + background-color: rgb(206, 0, 0); +} diff --git a/client/src/components/App.tsx b/client/src/components/App.tsx new file mode 100644 index 00000000..6f7b4f2d --- /dev/null +++ b/client/src/components/App.tsx @@ -0,0 +1,146 @@ +import * as React from 'react' +import { connect } from 'react-redux' +import { compose } from 'redux' +import { IStore } from '../../../shared/src/reducers/store' + +import '../assets/css/App.css' +import Channels from './Channels' +import Settings from './Settings' +import Storage from './RoutingStorage' +import MiniChannels from './MiniChannels' +import MicTally from './MicTally' +import { withTranslation } from 'react-i18next' +import PagesSettings from './PagesSettings' +import LabelSettings from './Labels' + +export interface IAppProps { + store: IStore + t: any +} + +class App extends React.Component { + constructor(props: IAppProps) { + super(props) + } + + componentWillMount() { + console.log( + 'http args : ', + window.location.search.includes('settings=1') + ) + window.socketIoClient.emit( + 'get-mixerprotocol', + 'get selected mixerprotocol' + ) + window.socketIoClient.emit('get-store', 'update local store') + window.socketIoClient.emit('get-settings', 'update local settings') + this.iFrameFocusHandler() + this.contextMenuHandler() + } + + public shouldComponentUpdate(nextProps: IAppProps) { + return ( + nextProps.store.settings[0].showSettings != + this.props.store.settings[0].showSettings || + nextProps.store.settings[0].showPagesSetup != + this.props.store.settings[0].showPagesSetup || + nextProps.store.settings[0].showLabelSettings != + this.props.store.settings[0].showLabelSettings || + nextProps.store.settings[0].serverOnline != + this.props.store.settings[0].serverOnline || + nextProps.store.settings[0].showStorage != + this.props.store.settings[0].showStorage + ) + } + + sendSofieMessage(type: string, payload?: any | '', replyTo?: string | '') { + window.top.postMessage( + { + id: Date.now().toString(), + replyToId: replyTo, + type: type, + payload: payload, + }, + '*' + ) + } + + iFrameFocusHandler() { + if (window.top !== window.self) { + this.sendSofieMessage('hello') + document.addEventListener( + 'click', + (e) => { + e.preventDefault() + this.sendSofieMessage('focus_in') + }, + true + ) + window.addEventListener('message', (event) => { + try { + const message = event.data + if (!message || !message.type) return + switch (message.type) { + case 'welcome': + console.log('Hosted by: ' + message.payload) + // finish three-way handshake + this.sendSofieMessage('ack', undefined, message.id) + break + } + } catch (e) { + console.log('Error Sofie API') + } + }) + } + } + + /** + * disables context menu in order to enable multi touch support + */ + contextMenuHandler() { + document.addEventListener( + 'contextmenu', + function (e) { + e.preventDefault() + }, + false + ) + } + + render() { + const urlParams = new URLSearchParams(window.location.search) + const viewId = urlParams.get('view') + return ( +
    + {!this.props.store.settings[0].serverOnline && ( +
    + {this.props.t('TRYING TO CONNECT TO SISYFOS SERVER')} +
    + )} + { (viewId === 'minimonitor') ? ( + + ) : (viewId === 'mic-tally') ? ( + + ) : ( + + )} + {this.props.store.settings[0].showLabelSettings && } + {this.props.store.settings[0].showPagesSetup && } + {this.props.store.settings[0].showStorage && } + {this.props.store.settings[0].showSettings && } +
    + ) + } +} + +const mapStateToProps = (state: any, t: any): IAppProps => { + return { + store: state, + t: t, + } +} + +export default compose( + connect(mapStateToProps), + withTranslation() +)(App) as any diff --git a/client/src/components/ChanStrip.tsx b/client/src/components/ChanStrip.tsx new file mode 100644 index 00000000..ccdbff58 --- /dev/null +++ b/client/src/components/ChanStrip.tsx @@ -0,0 +1,568 @@ +import React from 'react' +import ReactSlider from 'react-slider' + +import '../assets/css/ChanStrip.css' +import { Store } from 'redux' +import { connect } from 'react-redux' +import { + storeShowChanStrip, + storeShowOptions, + storeShowMonitorOptions, + storeShowChanStripFull, +} from '../../../shared/src/actions/settingsActions' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { + SOCKET_SET_FX, + SOCKET_SET_AUX_LEVEL, + SOCKET_SET_INPUT_GAIN, + SOCKET_SET_INPUT_SELECTOR, +} from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import ReductionMeter from './ReductionMeter' +import ClassNames from 'classnames' +import { fxParamsList } from '../../../shared/src/constants/MixerProtocolInterface' +import { getFaderLabel } from '../utils/labels' + +interface IChanStripInjectProps { + label: string + selectedProtocol: string + numberOfChannelsInType: Array + channel: Array + fader: Array + auxSendIndex: number + offtubeMode: boolean +} + +interface IChanStripProps { + faderIndex: number +} + +// Constants for Delay buttons: +const DEL_VALUES = [10, 1, -1, -10] + +class ChanStrip extends React.PureComponent< + IChanStripProps & IChanStripInjectProps & Store +> { + constructor(props: any) { + super(props) + } + + shouldComponentUpdate(nextProps: IChanStripInjectProps & IChanStripProps) { + if (nextProps.faderIndex > -1) { + return true + } else { + return false + } + } + + handleShowRoutingOptions() { + this.props.dispatch(storeShowOptions(this.props.faderIndex)) + this.props.dispatch(storeShowChanStrip(-1)) + } + + handleShowMonitorOptions() { + this.props.dispatch(storeShowMonitorOptions(this.props.faderIndex)) + this.props.dispatch(storeShowChanStrip(-1)) + } + handleShowChStripFull() { + this.props.dispatch(storeShowChanStripFull(this.props.faderIndex)) + } + handleClose = () => { + this.props.dispatch(storeShowChanStrip(-1)) + } + handleInputSelect(selected: number) { + window.socketIoClient.emit(SOCKET_SET_INPUT_SELECTOR, { + faderIndex: this.props.faderIndex, + selected: selected, + }) + } + handleInputGain(event: any) { + window.socketIoClient.emit(SOCKET_SET_INPUT_GAIN, { + faderIndex: this.props.faderIndex, + level: parseFloat(event), + }) + } + + changeDelay(currentValue: number, addValue: number) { + window.socketIoClient.emit(SOCKET_SET_FX, { + fxParam: fxParamsList.DelayTime, + channel: this.props.faderIndex, + level: currentValue + addValue, + }) + } + + handleFx(fxParam: fxParamsList, event: any) { + window.socketIoClient.emit(SOCKET_SET_FX, { + fxParam: fxParam, + channel: this.props.faderIndex, + level: parseFloat(event), + }) + } + + handleMonitorLevel(event: any, channelIndex: number) { + window.socketIoClient.emit(SOCKET_SET_AUX_LEVEL, { + channel: channelIndex, + auxIndex: this.props.auxSendIndex, + level: parseFloat(event), + }) + } + + inputSelectorButton(index: number) { + const isActive = + this.props.fader[this.props.faderIndex].inputSelector === index + 1 + return ( + + ) + } + + inputSelector() { + return ( +
    + {window.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_SELECTOR ? ( + + {window.mixerProtocol.channelTypes[0].toMixer.CHANNEL_INPUT_SELECTOR.map( + (none: any, index: number) => { + return this.inputSelectorButton(index) + } + )} + + ) : null} +
    + ) + } + + inputGain() { + let maxLabel: number = + window.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_INPUT_GAIN?.[0].maxLabel ?? 1 + let minLabel = + window.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_INPUT_GAIN?.[0].minLabel ?? 0 + return ( +
    + Gain +
    {maxLabel + ' dB'}
    + {window.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_GAIN ? ( + + { + this.handleInputGain(event) + }} + /> + + ) : null} +
    {minLabel + ' dB'}
    +
    + ) + } + + gainReduction() { + return ( +
    + Redution + +
    + ) + } + delay() { + return ( + + {this.fxParamFader(fxParamsList.DelayTime)} +
    + {DEL_VALUES.map((value: number) => { + return ( + + ) + })} +
    +
    + ) + } + + fxParamFader(fxParam: fxParamsList) { + let maxLabel: number = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam]?.[0] + .maxLabel ?? 1 + let minLabel = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam]?.[0] + .minLabel ?? 0 + let valueLabel = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam]?.[0] + .valueLabel ?? '' + let valueAsLabels = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam]?.[0] + .valueAsLabels + return ( +
    + {window.mixerProtocol.channelTypes[0].fromMixer[fxParam][0] + .label ?? ''} +
    + {!valueAsLabels + ? maxLabel + valueLabel + : valueAsLabels[valueAsLabels.length - 1] + valueLabel} +
    + ( +
    + {!valueAsLabels + ? Math.round( + (maxLabel - minLabel) * + parseFloat(state.valueNow) + + minLabel + ) + : valueAsLabels[ + Math.round( + parseFloat(state.valueNow) * + (maxLabel - minLabel) + ) + ]} + {valueLabel} +
    + )} + onChange={(event: any) => { + this.handleFx(fxParam, event) + }} + /> +
    + {!valueAsLabels + ? minLabel + valueLabel + : valueAsLabels[0] + valueLabel} +
    +
    + ) + } + + monitor(channelIndex: number) { + let faderIndex = this.props.channel[channelIndex].assignedFader + if (faderIndex === -1) return null + let monitorName = getFaderLabel(faderIndex, 'Fader') + return ( +
  • + {monitorName} + { + this.handleMonitorLevel(event, channelIndex) + }} + /> +

    _______

    +
  • + ) + } + + parameters() { + if (this.props.offtubeMode) { + const hasInput = + window.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_GAIN || + window.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_SELECTOR + const hasGainTrim = + window.mixerProtocol.channelTypes[0].toMixer[ + fxParamsList.GainTrim + ] + const hasComp = + window.mixerProtocol.channelTypes[0].toMixer[ + fxParamsList.CompThrs + ] || + window.mixerProtocol.channelTypes[0].toMixer[ + fxParamsList.CompRatio + ] + const hasDelay = + window.mixerProtocol.channelTypes[0].toMixer[ + fxParamsList.DelayTime + ] + const hasEq = + window.mixerProtocol.channelTypes[0].toMixer[ + fxParamsList.EqGain01 + ] || + window.mixerProtocol.channelTypes[0].toMixer[ + fxParamsList.EqGain02 + ] || + window.mixerProtocol.channelTypes[0].toMixer[ + fxParamsList.EqGain03 + ] || + window.mixerProtocol.channelTypes[0].toMixer[ + fxParamsList.EqGain04 + ] + const hasMonitorSends = this.props.channel.find( + (ch: any) => ch.auxLevel[this.props.auxSendIndex] >= 0 + ) + return ( +
    +
    + {hasInput && ( + +
    +
    INPUT
    +
    + {this.inputSelector()} + {this.inputGain()} +
    +
    +
    + )} + {hasGainTrim && ( + +
    +
    INPUT
    +
    + {this.fxParamFader( + fxParamsList.GainTrim + )} +
    +
    +
    + )} + {hasComp && ( + +
    +
    COMPRESSOR
    +
    + {this.fxParamFader( + fxParamsList.CompThrs + )} +

    ______

    + {this.fxParamFader( + fxParamsList.CompRatio + )} +

    ______

    + {this.gainReduction()} +
    +
    +
    + )} + {hasDelay && ( + +
    +
    DELAY
    +
    + {this.delay()} +
    +
    +
    + )} +
    + + {hasEq && ( + +
    +
    +
    +
    EQUALIZER
    +
    +
    + {window.mixerProtocol + .channelTypes[0].toMixer[ + fxParamsList.EqGain01 + ] ? ( + + {this.fxParamFader( + fxParamsList.EqGain01 + )} +

    + _______ +

    +
    + ) : null} + {window.mixerProtocol + .channelTypes[0].toMixer[ + fxParamsList.EqGain02 + ] ? ( + + {this.fxParamFader( + fxParamsList.EqGain02 + )} +

    + _______ +

    +
    + ) : null} + {window.mixerProtocol + .channelTypes[0].toMixer[ + fxParamsList.EqGain03 + ] ? ( + + {this.fxParamFader( + fxParamsList.EqGain03 + )} +

    + _______ +

    +
    + ) : null} + {window.mixerProtocol + .channelTypes[0].toMixer[ + fxParamsList.EqGain04 + ] ? ( + + {this.fxParamFader( + fxParamsList.EqGain04 + )} +

    + _______ +

    +
    + ) : null} +
    +
    +
    +
    +
    + )} + + {hasMonitorSends && ( + +
    +
    + {this.props.label} + {' - MONITOR MIX MINUS'} +
    +
      + {this.props.channel.map( + (ch: any, index: number) => { + if ( + ch.auxLevel[ + this.props.auxSendIndex + ] >= 0 + ) { + return this.monitor(index) + } + } + )} +
    +
    + )} +
    + ) + } else { + return null + } + } + + render() { + if (this.props.faderIndex >= 0) { + return ( +
    +
    + {this.props.label} + + +
    +
    + {this.parameters()} +
    + ) + } else { + return
    + } + } +} + +const mapStateToProps = (state: any, props: any): IChanStripInjectProps => { + let inject: IChanStripInjectProps = { + label: '', + selectedProtocol: state.settings[0].mixers[0].mixerProtocol, + numberOfChannelsInType: + state.settings[0].mixers[0].numberOfChannelsInType, + channel: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader, + auxSendIndex: -1, + offtubeMode: state.settings[0].offtubeMode, + } + if (props.faderIndex >= 0) { + inject = { + label: getFaderLabel(props.faderIndex, 'FADER'), + selectedProtocol: state.settings[0].mixers[0].mixerProtocol, + numberOfChannelsInType: + state.settings[0].mixers[0].numberOfChannelsInType, + channel: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader, + auxSendIndex: state.faders[0].fader[props.faderIndex].monitor - 1, + offtubeMode: state.settings[0].offtubeMode, + } + } + return inject +} + +export default connect(mapStateToProps)( + ChanStrip +) as any diff --git a/client/src/components/ChanStripEq.tsx b/client/src/components/ChanStripEq.tsx new file mode 100644 index 00000000..24a32985 --- /dev/null +++ b/client/src/components/ChanStripEq.tsx @@ -0,0 +1,456 @@ +import React from 'react' +import Draggable from 'react-draggable' +import ReactSlider from 'react-slider' + +import '../assets/css/ChanStripEq.css' +import { Store } from 'redux' +import { connect } from 'react-redux' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { IChannel } from '../../../shared/src/reducers/channelsReducer' +import { SOCKET_SET_FX } from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import { fxParamsList } from '../../../shared/src/constants/MixerProtocolInterface' +import { getFaderLabel } from '../utils/labels' + +interface IChanStripFullInjectProps { + label: string + selectedProtocol: string + numberOfChannelsInType: Array + channel: IChannel[] + fader: IFader[] + auxSendIndex: number + offtubeMode: boolean +} + +interface IChanStripFullProps { + faderIndex: number +} + +enum EqColors { + 'rgb(93, 184, 180)', + 'rgb(53, 112, 127)', + 'rgb(217, 21, 133)', + 'rgb(229, 159, 34)', +} + +interface IFreqLabels { + label: string + posY: number +} +const EQ_FREQ_LABELS: IFreqLabels[] = [ + { + label: '50', + posY: 340, + }, + { + label: '100', + posY: 525, + }, + { + label: '250', + posY: 780, + }, + { + label: '500', + posY: 950, + }, + { + label: '1k', + posY: 1135, + }, + { + label: '2k', + posY: 1350, + }, + { + label: '5k', + posY: 1575, + }, + { + label: '10k', + posY: 1755, + }, + { + label: '20k', + posY: 1950, + }, +] + +// Constant for calculation Eq dot positions: +const EQ_MIN_HZ = 20 +const EQ_MAX_HZ = 20000 +const EQ_X_SIZE = 0.66 +const EQ_X_OFFSET = 0.18 +const EQ_Y_SIZE = 0.25 +const EQ_Y_OFFSET = 0.55 + +class ChanStripEq extends React.PureComponent< + IChanStripFullProps & IChanStripFullInjectProps & Store +> { + canvas: HTMLCanvasElement | undefined + + constructor(props: any) { + super(props) + } + + shouldComponentUpdate( + nextProps: IChanStripFullInjectProps & IChanStripFullProps + ) { + if (nextProps.faderIndex > -1) { + return true + } else { + return false + } + } + + handleFx(fxParam: fxParamsList, level: any) { + if (level < 0) { + level = 0 + } + if (level > 1) { + level = 1 + } + // window.storeRedux.dispatch(storeFaderFx(fxParam, this.props.faderIndex, parseFloat(level))) + window.socketIoClient.emit(SOCKET_SET_FX, { + fxParam: fxParam, + channel: this.props.faderIndex, + level: parseFloat(level), + }) + } + + handleDragCaptureEq(key: number, totalWidth: number, totalHeight: number, event: any) { + let eqFreqKey = + fxParamsList[ + String(fxParamsList[key]).replace( + 'EqGain', + 'EqFreq' + ) as keyof typeof fxParamsList + ] + let eventX = event.clientX ?? event.touches[0].clientX + let eventY = event.clientY ?? event.touches[0].clientY + this.handleFx(eqFreqKey, this.freqPositionToValue(eventX, totalWidth)) + this.handleFx(key, this.gainPositionToValue(eventY, totalHeight)) + } + + valueToFreqPosition(value: number, totalWidth: number) { + return value * totalWidth * EQ_X_SIZE + } + freqPositionToValue(position: number, totalWidth: number) { + return (position - totalWidth * EQ_X_OFFSET) / (totalWidth * EQ_X_SIZE) + } + + valueToGainPosition(value: number, totalHeight: number) { + return totalHeight * EQ_Y_SIZE - value * (totalHeight * EQ_Y_SIZE) + } + gainPositionToValue(position: number, totalHeight: number) { + return ( + (totalHeight * EQ_Y_SIZE - (position - totalHeight * EQ_Y_OFFSET)) / (totalHeight * EQ_Y_SIZE) + ) + } + + logOscToLinFreq(value: number) { + return Math.round( + Math.pow( + 10, + value * (Math.log10(EQ_MAX_HZ) - Math.log10(EQ_MIN_HZ)) + + Math.log10(EQ_MIN_HZ) + ) + ) + } + + setRef = (el: HTMLCanvasElement) => { + this.canvas = el + this.paintEqBackground() + } + + paintEqBackground() { + if (!this.canvas) { + return + } + this.canvas.width = 2000 + this.canvas.height = 600 + const context = this.canvas.getContext('2d', { + antialias: false, + stencil: false, + preserveDrawingBuffer: true, + }) as CanvasRenderingContext2D + + if (!context) return + + // Fill background color: + + context.rect(70, 0, this.canvas.width, this.canvas.height) + context.fillStyle = '#2a42274d' + context.fill() + // Draw X-Y axis: + context.beginPath() + context.strokeStyle = 'white' + context.moveTo(70, 0) + context.lineTo(70, this.canvas.height) + context.stroke() + // Draw zero gain line: + context.beginPath() + context.strokeStyle = 'rgba(128, 128, 128, 0.244) 10px' + context.moveTo(70, this.canvas.height / 2) + context.lineTo(this.canvas.width, this.canvas.height / 2) + context.stroke() + // Freq on zero gain line: + context.beginPath() + EQ_FREQ_LABELS.forEach((freq: IFreqLabels) => { + context.font = '30px Ariel' + context.strokeStyle = 'white' + context.strokeText( + freq.label, + freq.posY, + this.canvas.height / 2 + 30 + ) + }) + // Freq on zero gain line: + context.strokeText( + String( + window.mixerProtocol.channelTypes[0].fromMixer[ + fxParamsList.EqGain01 + ]?.[0].maxLabel + ) + ' dB', + 1, + 20 + ) + context.strokeText('0 dB', 1, this.canvas.height / 2 + 20) + context.strokeText( + String( + window.mixerProtocol.channelTypes[0].fromMixer[ + fxParamsList.EqGain01 + ]?.[0].maxLabel + ) + ' dB', + 1, + this.canvas.height + ) + context.stroke() + } + + eqGraphics() { + return ( +
    + {Object.keys(fxParamsList) + .filter((fxKey: number | string) => { + return String(fxKey).includes('EqGain') + }) + .map((keyName: string) => { + let fxKey = keyName as keyof typeof fxParamsList + let eqFreqKey = + fxParamsList[ + fxKey.replace( + 'EqGain', + 'EqFreq' + ) as keyof typeof fxParamsList + ] + return ( + + this.handleDragCaptureEq( + fxParamsList[fxKey], + window.innerWidth, + window.innerHeight, + event + ) + } + > +
    + O +
    +
    + ) + })} +
    + ) + } + + eqText() { + return ( +
    + {Object.keys(fxParamsList) + .filter((fxKey: number | string) => { + return String(fxKey).includes('EqGain') + }) + .map((keyName: string, index: number) => { + let fxKey = keyName as keyof typeof fxParamsList + let eqFreqKey = + fxParamsList[ + fxKey.replace( + 'EqGain', + 'EqFreq' + ) as keyof typeof fxParamsList + ] + let eqQKey = + fxParamsList[ + fxKey.replace( + 'EqGain', + 'EqQ' + ) as keyof typeof fxParamsList + ] + let maxGain: number = + window.mixerProtocol.channelTypes[0].fromMixer[ + fxParamsList[fxKey] + ]?.[0].maxLabel ?? 1 + let minGain = + window.mixerProtocol.channelTypes[0].fromMixer[ + fxParamsList[fxKey] + ]?.[0].minLabel ?? 0 + + return ( +
    +
    + {' Gain : '} + {Math.round( + 10 * + ((maxGain - minGain) * + (this.props.fader[ + this.props.faderIndex + ][fxParamsList[fxKey]]?.[0] ?? 0) + + minGain) + ) / 10} + {' Freq :'} + {this.logOscToLinFreq( + this.props.fader[this.props.faderIndex][ + eqFreqKey + ]?.[0] ?? 0 + )} + {this.qFader(eqQKey)} +
    + ) + })} +
    + ) + } + + qFader(fxParam: fxParamsList) { + let maxLabel: number = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam]?.[0] + .maxLabel ?? 1 + let minLabel = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam]?.[0] + .minLabel ?? 0 + let valueLabel = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam]?.[0] + .valueLabel ?? '' + return ( +
    +
    + {Math.round( + ((maxLabel - minLabel) * + (1 - + Math.pow( + 1 - + this.props.fader[this.props.faderIndex][ + fxParam + ]?.[0], + 3 + )) + + minLabel) * + 10 + ) / 10} + {valueLabel} +
    + ( +
    + {Math.round( + ((maxLabel - minLabel) * + (1 - + Math.pow( + 1 - parseFloat(state.valueNow), + 3 + )) + + minLabel) * + 10 + ) / 10} + {valueLabel} +
    + )} + onChange={(event: any) => { + this.handleFx(fxParam, event) + }} + /> +
    + ) + } + + render() { + return ( +
    + +
    EQUALIZER
    + {this.eqGraphics()} + {this.eqText()} +
    + ) + } +} + +const mapStateToProps = (state: any, props: any): IChanStripFullInjectProps => { + let inject: IChanStripFullInjectProps = { + label: '', + selectedProtocol: state.settings[0].mixers[0].mixerProtocol, + numberOfChannelsInType: + state.settings[0].mixers[0].numberOfChannelsInType, + channel: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader, + auxSendIndex: -1, + offtubeMode: state.settings[0].offtubeMode, + } + if (props.faderIndex >= 0) { + inject = { + label: getFaderLabel(props.faderIndex, 'FADER'), + selectedProtocol: state.settings[0].mixers[0].mixerProtocol, + numberOfChannelsInType: + state.settings[0].mixers[0].numberOfChannelsInType, + channel: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader, + auxSendIndex: state.faders[0].fader[props.faderIndex].monitor - 1, + offtubeMode: state.settings[0].offtubeMode, + } + } + return inject +} + +export default connect(mapStateToProps)( + ChanStripEq +) as any diff --git a/client/src/components/ChanStripFull.tsx b/client/src/components/ChanStripFull.tsx new file mode 100644 index 00000000..03504a82 --- /dev/null +++ b/client/src/components/ChanStripFull.tsx @@ -0,0 +1,558 @@ +import React from 'react' +import ReactSlider from 'react-slider' + +import '../assets/css/ChanStripFull.css' +import { Store } from 'redux' +import { connect } from 'react-redux' +import { + storeShowOptions, + storeShowMonitorOptions, + storeShowChanStripFull, +} from '../../../shared/src/actions/settingsActions' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { + SOCKET_SET_FX, + SOCKET_SET_AUX_LEVEL, + SOCKET_SET_INPUT_GAIN, + SOCKET_SET_INPUT_SELECTOR, +} from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import ReductionMeter from './ReductionMeter' +import ClassNames from 'classnames' +import { fxParamsList } from '../../../shared/src/constants/MixerProtocolInterface' +import { IChannel } from '../../../shared/src/reducers/channelsReducer' +import { getFaderLabel } from '../utils/labels' +import ChanStripEq from './ChanStripEq' + +interface IChanStripFullInjectProps { + label: string + selectedProtocol: string + numberOfChannelsInType: Array + channel: IChannel[] + fader: IFader[] + auxSendIndex: number + offtubeMode: boolean +} + +interface IChanStripFullProps { + faderIndex: number +} + +// Constants for Delay buttons: +const DEL_VALUES = [10, 1, -1, -10] + +class ChanStripFull extends React.PureComponent< + IChanStripFullProps & IChanStripFullInjectProps & Store +> { + canvas: HTMLCanvasElement | undefined + + constructor(props: any) { + super(props) + } + + shouldComponentUpdate( + nextProps: IChanStripFullInjectProps & IChanStripFullProps + ) { + if (nextProps.faderIndex > -1) { + return true + } else { + return false + } + } + + handleShowRoutingOptions() { + this.props.dispatch(storeShowOptions(this.props.faderIndex)) + this.props.dispatch(storeShowChanStripFull(-1)) + } + + handleShowMonitorOptions() { + this.props.dispatch(storeShowMonitorOptions(this.props.faderIndex)) + this.props.dispatch(storeShowChanStripFull(-1)) + } + + handleClose = () => { + this.props.dispatch(storeShowChanStripFull(-1)) + } + handleInputSelect(selected: number) { + window.socketIoClient.emit(SOCKET_SET_INPUT_SELECTOR, { + faderIndex: this.props.faderIndex, + selected: selected, + }) + } + handleInputGain(event: any) { + window.socketIoClient.emit(SOCKET_SET_INPUT_GAIN, { + faderIndex: this.props.faderIndex, + level: parseFloat(event), + }) + } + + changeDelay(currentValue: number, addValue: number) { + window.socketIoClient.emit(SOCKET_SET_FX, { + fxParam: fxParamsList.DelayTime, + channel: this.props.faderIndex, + level: currentValue + addValue, + }) + } + + handleFx(fxParam: fxParamsList, level: any) { + if (level < 0) { + level = 0 + } + if (level > 1) { + level = 1 + } + // window.storeRedux.dispatch(storeFaderFx(fxParam, this.props.faderIndex, parseFloat(level))) + window.socketIoClient.emit(SOCKET_SET_FX, { + fxParam: fxParam, + channel: this.props.faderIndex, + level: parseFloat(level), + }) + } + + handleMonitorLevel(event: any, channelIndex: number) { + window.socketIoClient.emit(SOCKET_SET_AUX_LEVEL, { + channel: channelIndex, + auxIndex: this.props.auxSendIndex, + level: parseFloat(event), + }) + } + + inputSelectorButton(index: number) { + const isActive = + this.props.fader[this.props.faderIndex].inputSelector === index + 1 + return ( + + ) + } + + inputSelector() { + return ( +
    + {window.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_SELECTOR ? ( + + {window.mixerProtocol.channelTypes[0].toMixer.CHANNEL_INPUT_SELECTOR.map( + (none: any, index: number) => { + return this.inputSelectorButton(index) + } + )} + + ) : null} +
    + ) + } + + inputGain() { + let maxLabel: number = + window.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_INPUT_GAIN?.[0].maxLabel ?? 1 + let minLabel = + window.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_INPUT_GAIN?.[0].minLabel ?? 0 + return ( +
    + Gain +
    {maxLabel + ' dB'}
    + {window.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_GAIN ? ( + + { + this.handleInputGain(event) + }} + /> + + ) : null} +
    {minLabel + ' dB'}
    +
    + ) + } + + gainReduction() { + return ( +
    + Redution + +
    + ) + } + delay() { + return ( + + {this.fxParamFader(fxParamsList.DelayTime)} +
    + {DEL_VALUES.map((value: number) => { + return ( + + ) + })} +
    +
    + ) + } + + fxParamFader(fxParam: fxParamsList) { + if (!this.doesParamExists(fxParam)) { + return + } + let maxLabel: number = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam][0] + .maxLabel ?? 1 + let minLabel = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam][0] + .minLabel ?? 0 + let valueLabel = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam]?.[0] + .valueLabel ?? '' + let valueAsLabels = + window.mixerProtocol.channelTypes[0].fromMixer[fxParam]?.[0] + .valueAsLabels + return ( +
    + {window.mixerProtocol.channelTypes[0].fromMixer[fxParam][0] + .label ?? ''} +
    + {!valueAsLabels + ? maxLabel + valueLabel + : valueAsLabels[valueAsLabels.length - 1] + valueLabel} +
    + ( +
    + {!valueAsLabels + ? Math.round( + (maxLabel - minLabel) * + parseFloat(state.valueNow) + + minLabel + ) + : valueAsLabels[ + Math.round( + parseFloat(state.valueNow) * + (maxLabel - minLabel) + ) + ]} + {valueLabel} +
    + )} + onChange={(event: any) => { + this.handleFx(fxParam, event) + }} + /> +
    + {!valueAsLabels + ? minLabel + valueLabel + : valueAsLabels[0] + valueLabel} +
    +
    + ) + } + + fxParamButton(fxParam: fxParamsList) { + if (!this.doesParamExists(fxParam)) { + return + } + let value = this.props.fader[this.props.faderIndex][fxParam]?.[0] + return ( +
    +
    + {window.mixerProtocol.channelTypes[0].fromMixer[fxParam][0] + .label ?? ''} +
    + +
    + ) + } + + monitor(channelIndex: number) { + let faderIndex = this.props.channel[channelIndex].assignedFader + if (faderIndex === -1) return null + let monitorName = getFaderLabel(faderIndex, 'Fader') + return ( +
  • + {monitorName} +
     
    + { + this.handleMonitorLevel(event, channelIndex) + }} + /> +

    _______

    +
  • + ) + } + + doesParamExists(fxParam: fxParamsList): boolean { + return !!window.mixerProtocol.channelTypes[0].fromMixer[fxParam] + } + + parameters() { + if (this.props.offtubeMode) { + const hasInput = + window.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_GAIN || + window.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_SELECTOR + return ( +
    + {hasInput && ( + +
    +
    INPUT
    +
    + {this.inputSelector()} + {this.inputGain()} +
    +
    +
    + )} + + {this.doesParamExists(fxParamsList.GainTrim) ? ( +
    +
    INPUT
    +
    + {this.fxParamFader(fxParamsList.GainTrim)} +
    +
    + ) : ( + + )} + {this.doesParamExists(fxParamsList.CompThrs) ? ( +
    +
    COMPRESSOR
    +
    + {this.fxParamButton(fxParamsList.CompOnOff)} + {this.fxParamFader(fxParamsList.CompThrs)} +

    + ______ +

    + {this.fxParamFader(fxParamsList.CompRatio)} +

    + ______ +

    + {this.gainReduction()} + {this.fxParamFader(fxParamsList.CompMakeUp)} +

    + ______ +

    + {this.fxParamFader(fxParamsList.CompAttack)} +

    + ______ +

    + {this.fxParamFader(fxParamsList.CompHold)} +

    + ______ +

    + {this.fxParamFader( + fxParamsList.CompRelease + )} +

    + ______ +

    +
    +
    + ) : ( + + )} + {this.doesParamExists(fxParamsList.DelayTime) ? ( +
    +
    DELAY
    +
    + {this.delay()} +
    +
    + ) : ( +
    + )} +
    +
    + {this.props.label} + {' - MONITOR MIX MINUS'} +
    +
    +
      + {this.props.channel.map( + (ch: any, index: number) => { + if ( + ch.auxLevel[ + this.props.auxSendIndex + ] >= 0 + ) { + return this.monitor(index) + } + } + )} +
    +
    +
    +
    +
    + ) + } else { + return null + } + } + + eq() { + return ( + + {this.doesParamExists(fxParamsList.EqGain01) ? ( +
    + +
    + ) : ( + + )} +
    + ) + } + render() { + if (this.props.faderIndex >= 0) { + return ( +
    +
    + {this.props.label} + + {window.location.search.includes('settings=1') ? ( + + ) : null} + {window.location.search.includes('settings=1') ? ( + + ) : null} +
    +
    + {this.parameters()} +
    + {this.eq()} +
    + ) + } else { + return
    + } + } +} + +const mapStateToProps = (state: any, props: any): IChanStripFullInjectProps => { + let inject: IChanStripFullInjectProps = { + label: '', + selectedProtocol: state.settings[0].mixers[0].mixerProtocol, + numberOfChannelsInType: + state.settings[0].mixers[0].numberOfChannelsInType, + channel: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader, + auxSendIndex: -1, + offtubeMode: state.settings[0].offtubeMode, + } + if (props.faderIndex >= 0) { + inject = { + label: getFaderLabel(props.faderIndex, 'FADER'), + selectedProtocol: state.settings[0].mixers[0].mixerProtocol, + numberOfChannelsInType: + state.settings[0].mixers[0].numberOfChannelsInType, + channel: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader, + auxSendIndex: state.faders[0].fader[props.faderIndex].monitor - 1, + offtubeMode: state.settings[0].offtubeMode, + } + } + return inject +} + +export default connect(mapStateToProps)( + ChanStripFull +) as any diff --git a/client/src/components/Channel.tsx b/client/src/components/Channel.tsx new file mode 100644 index 00000000..a27e5ab0 --- /dev/null +++ b/client/src/components/Channel.tsx @@ -0,0 +1,513 @@ +import * as React from 'react' +import ClassNames from 'classnames' +import { connect } from 'react-redux' +import VuMeter from './VuMeter' +import { Store, compose } from 'redux' +import Nouislider from 'nouislider-react' +import '../assets/css/NoUiSlider.css' + +//assets: +import '../assets/css/Channel.css' +import * as IO from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import { IChannelReference, IFader } from '../../../shared/src/reducers/fadersReducer' +import { ISettings } from '../../../shared/src/reducers/settingsReducer' +import { storeShowChanStrip } from '../../../shared/src/actions/settingsActions' +import { withTranslation } from 'react-i18next' +import { VuLabelConversionType } from '../../shared../../../shared/src/constants/MixerProtocolInterface' +import { getFaderLabel } from '../utils/labels' +import { Conversions } from '../../../shared/src/actions/utils/dbConversion' + +interface IChannelInjectProps { + t: any + fader: IFader + settings: ISettings + channelType: number + channelTypeIndex: number + label: string +} + +interface IChannelProps { + faderIndex: number +} + +function XOR(a: any, b: any): boolean { + return (a && !b) || (b && !a) +} + +class Channel extends React.Component< + IChannelProps & IChannelInjectProps & Store +> { + faderIndex: number + + private _domRef: React.RefObject = React.createRef() + + constructor(props: any) { + super(props) + this.faderIndex = this.props.faderIndex + } + + public shouldComponentUpdate(nextProps: IChannelInjectProps) { + return ( + nextProps.channelTypeIndex !== this.props.channelTypeIndex || + nextProps.fader.pgmOn != this.props.fader.pgmOn || + nextProps.fader.voOn != this.props.fader.voOn || + nextProps.fader.pstOn != this.props.fader.pstOn || + nextProps.fader.pflOn != this.props.fader.pflOn || + nextProps.fader.muteOn != this.props.fader.muteOn || + nextProps.fader.slowFadeOn != this.props.fader.slowFadeOn || + nextProps.fader.ignoreAutomation != + this.props.fader.ignoreAutomation || + nextProps.fader.showChannel != this.props.fader.showChannel || + nextProps.fader.faderLevel != this.props.fader.faderLevel || + nextProps.label != this.props.label || + nextProps.settings.mixers[0].mixerProtocol != + this.props.settings.mixers[0].mixerProtocol || + nextProps.settings.showPfl != this.props.settings.showPfl || + nextProps.settings.showChanStrip != + this.props.settings.showChanStrip || + nextProps.fader.amixOn != this.props.fader.amixOn || + XOR(nextProps.fader.capabilities, this.props.fader.capabilities) || + XOR( + nextProps.fader.capabilities?.hasAMix, + this.props.fader.capabilities?.hasAMix + ) + ) + } + + componentDidUpdate() { + // scroll into view if we are now the chan strip + if (this.props.settings.showChanStrip === this.faderIndex) { + this._domRef.current?.scrollIntoView() + } + } + + handlePgm() { + window.socketIoClient.emit(IO.SOCKET_TOGGLE_PGM, this.faderIndex) + } + + handleVo() { + window.socketIoClient.emit(IO.SOCKET_TOGGLE_VO, this.faderIndex) + } + + handleSlowFade() { + window.socketIoClient.emit(IO.SOCKET_TOGGLE_SLOW_FADE, this.faderIndex) + } + + handlePst() { + window.socketIoClient.emit(IO.SOCKET_TOGGLE_PST, this.faderIndex) + } + + handlePfl() { + window.socketIoClient.emit(IO.SOCKET_TOGGLE_PFL, this.faderIndex) + if ( + this.props.settings.chanStripFollowsPFL && + !this.props.fader.pflOn && + this.props.settings.showChanStrip !== this.faderIndex + ) { + this.handleShowChanStrip() + } + } + + handleMute() { + window.socketIoClient.emit(IO.SOCKET_TOGGLE_MUTE, this.faderIndex) + } + + handleAmix() { + window.socketIoClient.emit(IO.SOCKET_TOGGLE_AMIX, this.faderIndex) + } + + handleIgnore() { + window.socketIoClient.emit(IO.SOCKET_TOGGLE_IGNORE, this.faderIndex) + } + + handleLevel(event: any) { + window.socketIoClient.emit(IO.SOCKET_SET_FADERLEVEL, { + faderIndex: this.faderIndex, + level: parseFloat(event), + }) + } + + handleZeroLevel() { + window.socketIoClient.emit(IO.SOCKET_SET_FADERLEVEL, { + faderIndex: this.faderIndex, + level: window.mixerProtocol.meter.zero, + }) + } + + handleShowChanStrip() { + this.props.dispatch(storeShowChanStrip(this.faderIndex)) + } + + handleVuMeter() { + if ( + window.mixerProtocol.protocol === 'CasparCG' || + window.mixerProtocol.protocol === 'VMIX' + ) { + return ( + + {!window.location.search.includes('vu=0') && + window.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_VU?.map( + (_, i) => ( + + ) + )}{' '} + + ) + } else { + let assignedChannels: IChannelReference[] = this.props.fader + .assignedChannels || [{ mixerIndex: 0, channelIndex: 0 }] + return ( + + {!window.location.search.includes('vu=0') && + assignedChannels?.map( + (assigned: IChannelReference, index) => ( + + ) + )}{' '} + + ) + } + } + + fader() { + const showFormat = !!window.mixerProtocol.vuLabelConversionType + const values = (showFormat && window.mixerProtocol.vuLabelValues) || [ + 0.75, + ] + let format = { + to: (f: number) => 0, + from: (d: number) => 0, + } + if (showFormat) { + if ( + window.mixerProtocol.vuLabelConversionType === + VuLabelConversionType.Linear + ) { + const range = window.mixerProtocol.fader + format = { + to: (f: number) => { + if (!range) return f + return (range.max - range.min) * f + range.max + }, + from: (d: number) => { + if (!range) return d + return (d - range.min) / (range.max - range.min) + }, + } + } else if ( + Conversions[ + window.mixerProtocol + .vuLabelConversionType as keyof typeof Conversions + ] + ) { + format = Conversions[VuLabelConversionType.Decibel] + } + } + return ( + { + this.handleLevel(event) + }} + pips={{ + mode: 'values', + values, + format, + filter: (v: number) => { + if (values.includes(v)) { + if (v === 0.75) { + return 1 // large + } else { + return 2 // small + } + } else { + return -1 // no pip + } + }, + }} + /> + ) + } + + zeroButton = () => { + return ( + + ) + } + + pgmButton = () => { + return ( + + ) + } + + voButton = () => { + return ( + + ) + } + + slowButton = () => { + return ( + + ) + } + + pstButton = () => { + return ( + + ) + } + + chanStripButton = () => { + const isActive = this.props.settings.showChanStrip === this.faderIndex + return ( + + ) + } + + pflButton = () => { + return ( + + ) + } + + ignoreButton = () => { + return ( + + ) + } + + muteButton = () => { + return ( + window.mixerProtocol.channelTypes[0].toMixer.CHANNEL_MUTE_ON && ( + + ) + ) + } + + amixButton = () => { + return ( + window.mixerProtocol.channelTypes[0].toMixer.CHANNEL_AMIX && ( + + ) + ) + } + + render() { + return this.props.fader.showChannel === false ? null : ( +
    +
    + {this.ignoreButton()} + {/* TODO - amix and mute cannot be shown at the same time due to css. Depends on protocol right now. */} + {this.muteButton()} + {this.amixButton()} +
    +
    + {this.handleVuMeter()} + {this.fader()} + {this.zeroButton()} +
    +
    + {this.pgmButton()} + + {this.props.settings.automationMode + ? this.voButton() + : this.slowButton()} +
    +
    +
    + {this.chanStripButton()} + {this.props.settings.showPfl + ? this.pflButton() + : this.pstButton()} +
    +
    + ) + } +} + +const mapStateToProps = (state: any, props: any): IChannelInjectProps => { + return { + t: props.t, + fader: state.faders[0].fader[props.faderIndex], + settings: state.settings[0], + channelType: 0 /* TODO: state.channels[0].channel[props.channelIndex].channelType, */, + channelTypeIndex: + props.faderIndex /* TODO: state.channels[0].channel[props.channelIndex].channelTypeIndex, */, + label: getFaderLabel(props.faderIndex), + } +} + +export default compose( + connect(mapStateToProps), + withTranslation() +)(Channel) as any diff --git a/client/src/components/ChannelMonitorOptions.tsx b/client/src/components/ChannelMonitorOptions.tsx new file mode 100644 index 00000000..a9af7284 --- /dev/null +++ b/client/src/components/ChannelMonitorOptions.tsx @@ -0,0 +1,202 @@ +import React, { ChangeEvent } from 'react' +import ClassNames from 'classnames' + +import '../assets/css/ChannelMonitorOptions.css' +import { Store } from 'redux' +import { connect } from 'react-redux' +import { storeShowMonitorOptions } from '../../../shared/src/actions/settingsActions' +import { ISettings } from '../../../shared/src/reducers/settingsReducer' +import { + SOCKET_SET_AUX_LEVEL, + SOCKET_SET_FADER_MONITOR, + SOCKET_SHOW_IN_MINI_MONITOR, +} from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import { getFaderLabel } from '../utils/labels' + +interface IMonitorSettingsInjectProps { + label: string + selectedProtocol: string + numberOfChannelsInType: Array + channel: Array + fader: Array + settings: ISettings +} + +interface IChannelProps { + faderIndex: number +} + +class ChannelMonitorOptions extends React.PureComponent< + IChannelProps & IMonitorSettingsInjectProps & Store +> { + faderIndex: number + + constructor(props: any) { + super(props) + this.faderIndex = this.props.faderIndex + } + + handleAssignChannel(channel: number, event: any) { + if (event.target.checked === false) { + if (window.confirm('Remove monitoring on ' + String(channel + 1))) { + window.socketIoClient.emit(SOCKET_SET_AUX_LEVEL, { + channel: channel, + auxIndex: this.props.fader[this.faderIndex].monitor - 1, + level: -1, + }) + } + } else { + if ( + window.confirm( + 'Enable monitoring of Channel ' + String(channel + 1) + '?' + ) + ) { + window.socketIoClient.emit(SOCKET_SET_AUX_LEVEL, { + channel: channel, + auxIndex: this.props.fader[this.faderIndex].monitor - 1, + level: 0, + }) + } + } + } + + handleClearMonitorRouting() { + if ( + window.confirm( + 'This will remove all monitor assignments to Aux :' + + String(this.props.fader[this.faderIndex].monitor) + ) + ) { + this.props.channel.forEach((channel: any, index: number) => { + window.socketIoClient.emit(SOCKET_SET_AUX_LEVEL, { + channel: index, + auxIndex: this.props.fader[this.faderIndex].monitor - 1, + level: -1, + }) + }) + } + } + + handleMixMinusRouting() { + if ( + window.confirm( + 'Send all channels to Aux: ' + + String(this.props.fader[this.faderIndex].monitor) + ) + ) { + this.props.channel.forEach((channel: any, index: number) => { + window.socketIoClient.emit(SOCKET_SET_AUX_LEVEL, { + channel: index, + auxIndex: this.props.fader[this.faderIndex].monitor - 1, + level: 0, + }) + }) + } + } + + handleShowInMiniMonitor = (event: ChangeEvent) => { + window.socketIoClient.emit(SOCKET_SHOW_IN_MINI_MONITOR, { + faderIndex: this.faderIndex, + showInMiniMonitor: event.target.checked, + }) + } + + handleSetAux = (event: ChangeEvent) => { + let value = parseFloat(event.target.value) || -1 + if (value > this.props.settings.mixers[0].numberOfAux || value < 0) { + value = -1 + } + window.socketIoClient.emit(SOCKET_SET_FADER_MONITOR, { + faderIndex: this.faderIndex, + auxIndex: value, + }) + } + + handleClose = () => { + this.props.dispatch(storeShowMonitorOptions(this.faderIndex)) + } + + render() { + return ( +
    +

    MONITOR ROUTE

    +

    {this.props.label}

    + + + +
    + + this.handleSetAux(event)} + /> +
    + + this.handleShowInMiniMonitor(event)} + /> +
    + {this.props.channel.map((channel: any, index: number) => { + let isSelected: boolean = + this.props.channel[index].auxLevel[ + this.props.fader[this.faderIndex].monitor - 1 + ] + return ( +
    + {' Channel ' + (index + 1) + ' : '} + + this.handleAssignChannel(index, event) + } + /> + {isSelected ? 'Monitor this' : null} +
    + ) + })} +
    + ) + } +} + +const mapStateToProps = ( + state: any, + props: any +): IMonitorSettingsInjectProps => { + return { + label: getFaderLabel(props.faderIndex, 'FADER'), + selectedProtocol: state.settings[0].mixers[0].mixerProtocol, + numberOfChannelsInType: + state.settings[0].mixers[0].numberOfChannelsInType, + channel: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader, + settings: state.settings[0], + } +} + +export default connect(mapStateToProps)( + ChannelMonitorOptions +) as any diff --git a/client/src/components/ChannelRouteSettings.tsx b/client/src/components/ChannelRouteSettings.tsx new file mode 100644 index 00000000..9bee92a6 --- /dev/null +++ b/client/src/components/ChannelRouteSettings.tsx @@ -0,0 +1,197 @@ +import React from 'react' +import ClassNames from 'classnames' + +import '../assets/css/ChannelRouteSettings.css' +import { Store } from 'redux' +import { connect } from 'react-redux' +import { storeShowOptions } from '../../../shared/src/actions/settingsActions' +import { SOCKET_SET_ASSIGNED_FADER } from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import { IchMixerConnection } from '../../../shared/src/reducers/channelsReducer' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { getFaderLabel } from '../utils/labels' + +interface IChannelSettingsInjectProps { + label: string + chMixerConnections: IchMixerConnection[] + fader: IFader[] +} + +interface IChannelProps { + faderIndex: number +} + +class ChannelRouteSettings extends React.PureComponent< + IChannelProps & IChannelSettingsInjectProps & Store +> { + faderIndex: number + + constructor(props: any) { + super(props) + this.faderIndex = this.props.faderIndex + } + + handleAssignChannel(mixerIndex: number, channel: number, event: any) { + if (event.target.checked === false) { + console.log('Unbinding Channel') + if ( + window.confirm( + 'Unbind Mixer ' + + String(mixerIndex + 1) + + ' Channel ' + + String(channel + 1) + + ' from Fader ' + + String(this.faderIndex + 1) + ) + ) { + window.socketIoClient.emit(SOCKET_SET_ASSIGNED_FADER, { + mixerIndex: mixerIndex, + channel: channel, + faderAssign: -1, + }) + } + } else { + console.log('Binding Channel') + if ( + window.confirm( + 'Bind Mixer ' + + String(mixerIndex + 1) + + ' Channel ' + + String(channel + 1) + + ' to Fader ' + + String(this.faderIndex + 1) + + '?' + ) + ) { + window.socketIoClient.emit(SOCKET_SET_ASSIGNED_FADER, { + mixerIndex: mixerIndex, + channel: channel, + faderAssign: this.faderIndex, + }) + } + } + } + + handleClearRouting() { + if (window.confirm('REMOVE ALL FADER ASSIGNMENTS????')) { + this.props.chMixerConnections.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + chMixerConnection.channel.forEach( + (channel: any, index: number) => { + window.socketIoClient.emit( + SOCKET_SET_ASSIGNED_FADER, + { + mixerIndex: mixerIndex, + channel: index, + faderAssign: -1, + } + ) + } + ) + } + ) + } + } + + handle11Routing() { + if (window.confirm('Reassign all Faders 1:1 to Channels????')) { + this.props.fader.forEach((fader: any, index: number) => { + if (this.props.chMixerConnections[0].channel.length > index) { + window.socketIoClient.emit(SOCKET_SET_ASSIGNED_FADER, { + mixerIndex: 0, + channel: index, + faderAssign: index, + }) + } + }) + } + } + + handleClose = () => { + this.props.dispatch(storeShowOptions(this.faderIndex)) + } + + renderMixer(chMixerConnection: IchMixerConnection, mixerIndex: number) { + return ( +
    +

    + {' '} + {'MIXER ' + (mixerIndex + 1)} +

    + {chMixerConnection.channel.map((channel: any, index: number) => { + return ( +
    + {' Channel ' + (index + 1) + ' : '} + + this.handleAssignChannel( + mixerIndex, + index, + event + ) + } + /> + {channel.assignedFader >= 0 + ? ' (Fader ' + + (channel.assignedFader + 1) + + ')' + : ' (not assigned)'} +
    + ) + })} +
    + ) + } + + render() { + return ( +
    +

    {this.props.label}

    + + + +
    + {this.props.chMixerConnections.map( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => + this.renderMixer(chMixerConnection, mixerIndex) + )} +
    + ) + } +} + +const mapStateToProps = ( + state: any, + props: any +): IChannelSettingsInjectProps => { + return { + label: getFaderLabel(props.faderIndex, 'FADER'), + chMixerConnections: state.channels[0].chMixerConnection, + fader: state.faders[0].fader, + } +} + +export default connect(mapStateToProps)( + ChannelRouteSettings +) as any diff --git a/client/src/components/Channels.tsx b/client/src/components/Channels.tsx new file mode 100644 index 00000000..e3aa4885 --- /dev/null +++ b/client/src/components/Channels.tsx @@ -0,0 +1,366 @@ +import * as React from 'react' +import { connect } from 'react-redux' +import ClassNames from 'classnames' + +import Channel from './Channel' +import '../assets/css/Channels.css' +import { Store } from 'redux' +import { + storeSetPage, + storeShowLabelSetup, + storeShowPagesSetup, + storeShowSettings, + storeShowStorage, +} from '../../../shared/src/actions/settingsActions' +import ChannelRouteSettings from './ChannelRouteSettings' +import ChanStrip from './ChanStrip' +import ChannelMonitorOptions from './ChannelMonitorOptions' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { IChannels } from '../../../shared/src/reducers/channelsReducer' +import { + ICustomPages, + IMixerSettings, + ISettings, + PageType, +} from '../../../shared/src/reducers/settingsReducer' +import { + SOCKET_NEXT_MIX, + SOCKET_CLEAR_PST, + SOCKET_RESTART_SERVER, + SOCKET_TOGGLE_ALL_MANUAL, +} from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import ChanStripFull from './ChanStripFull' + +interface IChannelsInjectProps { + channels: IChannels + faders: IFader[] + settings: ISettings + customPages: ICustomPages[] + mixersOnline: boolean +} + +class Channels extends React.Component { + constructor(props: any) { + super(props) + this.props.settings.showMonitorOptions = -1 + } + + public shouldComponentUpdate(nextProps: IChannelsInjectProps) { + return ( + this.props.settings.showOptions !== + nextProps.settings.showOptions || + this.props.settings.showChanStrip !== + nextProps.settings.showChanStrip || + this.props.settings.showChanStripFull !== + nextProps.settings.showChanStripFull || + this.props.settings.showMonitorOptions !== + nextProps.settings.showMonitorOptions || + this.props.settings.customPages !== + nextProps.settings.customPages || + this.props.mixersOnline !== nextProps.mixersOnline || + this.props.faders.length !== nextProps.faders.length || + this.props.settings.currentPage !== + nextProps.settings.currentPage || + this.props.settings.numberOfCustomPages !== + nextProps.settings.numberOfCustomPages || + !!nextProps.faders.find( + (f, i) => + this.props.faders[i].ignoreAutomation !== f.ignoreAutomation + ) + ) + } + + handleMix() { + window.socketIoClient.emit(SOCKET_NEXT_MIX) + } + + handleClearAllPst() { + window.socketIoClient.emit(SOCKET_CLEAR_PST) + } + + handleAllManual() { + window.socketIoClient.emit(SOCKET_TOGGLE_ALL_MANUAL) + } + + handleReconnect() { + if (window.confirm('Are you sure you will restart server?')) { + window.socketIoClient.emit(SOCKET_RESTART_SERVER) + } + } + + handleShowSettings() { + this.props.dispatch(storeShowSettings()) + } + + handleShowStorage() { + this.props.dispatch(storeShowStorage()) + } + + handleShowPagesSetting() { + this.props.dispatch(storeShowPagesSetup()) + } + + handleShowLabelSetting() { + this.props.dispatch(storeShowLabelSetup()) + } + + handlePages(type: PageType, i: number | string) { + this.props.dispatch(storeSetPage(type, i)) + } + + renderPageButtons() { + if (this.props.settings.enablePages === false) { + return undefined + } + + const curPage = this.props.settings.currentPage + + const customPageButtons = [] + const pages = this.props.customPages + if (pages) { + for (const p of pages) { + const isActive = + curPage.type === PageType.CustomPage && curPage.id === p.id + customPageButtons.push( + + ) + } + } + + const isAllActive = curPage.type === PageType.All + return ( + + {customPageButtons} + {/*numberedButtons*/} + + + ) + } + + renderAllManualButton() { + // TODO - ignore disabled / hidden faders? + const isAllManual = + this.props.faders.find((f) => f.ignoreAutomation !== true) === + undefined + const isAnyManual = !!this.props.faders.find( + (f) => f.ignoreAutomation === true + ) + + console.log('all manual', isAllManual, 'any manual', isAnyManual) + + return ( + + + + ) + } + + renderFaders() { + const curPage = this.props.settings.currentPage + switch (curPage.type) { + case PageType.All: + return this.props.faders.map((value, index) => ( + + )) + case PageType.CustomPage: + let pageIndex: number = this.props.customPages + .map((item: ICustomPages) => item.id) + .indexOf(curPage.id || '') + return this.props.customPages[pageIndex].faders + .filter((value) => { + return ( + value >= 0 && + value < this.props.settings.numberOfFaders + ) + }) + .map((faderIndex, index) => { + return ( + + ) + }) + } + } + + render() { + return ( +
    + {typeof this.props.settings.showOptions === 'number' ? ( + + ) : null} + {this.props.settings.showChanStrip >= 0 ? ( +
    + +
    + ) : ( +
    + +
    + )} + {this.props.settings.showChanStripFull >= 0 ? ( + + ) : ( +
    + )} + + {this.props.settings.showMonitorOptions >= 0 ? ( + + ) : null} +
    {this.renderFaders()}
    +
    +
    +
    + {this.props.mixersOnline ? ( + + ) : ( + + )} + + {window.location.search.includes('settings=1') ? ( + + ) : null} + + + + {window.location.search.includes('settings=1') ? ( + + ) : null} + + {window.location.search.includes('settings=1') ? ( + + ) : null} +
    +
    + {this.renderAllManualButton()} + {!this.props.settings.showPfl && ( + + + + + )} +
    +
    {this.renderPageButtons()}
    +
    +
    + ) + } +} + +const mapStateToProps = (state: any): IChannelsInjectProps => { + return { + channels: state.channels[0].chMixerConnection[0].channel, + faders: state.faders[0].fader, + customPages: state.settings[0].customPages, + settings: state.settings[0], + mixersOnline: state.settings[0].mixers + .map((m: IMixerSettings) => m.mixerOnline) + .reduce((a: boolean, b: boolean) => a && b), + } +} + +export default connect(mapStateToProps)( + Channels +) diff --git a/client/src/components/Labels.tsx b/client/src/components/Labels.tsx new file mode 100644 index 00000000..92b1f012 --- /dev/null +++ b/client/src/components/Labels.tsx @@ -0,0 +1,159 @@ +import React, { ChangeEvent } from 'react' + +import '../assets/css/LabelSettings.css' +import { Store } from 'redux' +import { connect } from 'react-redux' +import { + storeShowLabelSetup, +} from '../../../shared/src/actions/settingsActions' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { + SOCKET_FLUSH_LABELS, + SOCKET_SET_LABELS, +} from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import { ICustomPages } from '../../../shared/src/reducers/settingsReducer' +import { getChannelLabel } from '../utils/labels' +import { flushExtLabels, updateLabels } from '../../../shared/src/actions/faderActions' +import { storeFlushChLabels } from '../../../shared/src/actions/channelActions' + +interface ILabelSettingsInjectProps { + customPages: ICustomPages[] + fader: IFader[] +} + +class LabelSettings extends React.PureComponent< + ILabelSettingsInjectProps & Store +> { + state = { + mutations: {} as Record + } + + constructor(props: any) { + super(props) + } + + componentDidMount() { + this.setState({ label: this.props.customPages[0].label }) + } + + handleLabel = (event: ChangeEvent, index: number) => { + console.log(event.target.value, index) + this.setState({ mutations: { ...this.state.mutations, [index]: event.target.value }}) + } + + handleClearLabels() { + if (window.confirm('Clear all user defined labels?')) { + const faders = this.props.fader + .map((f, i) => ({ label: f.userLabel, i })) + .filter(f => f.label) + .reduce((a, b) => ({ ...a, [b.i]: '' }), {} as Record) + + this.props.dispatch(updateLabels(faders)) + this.props.dispatch(storeShowLabelSetup()) + window.socketIoClient.emit(SOCKET_SET_LABELS, { update: faders }) + } + } + + handleFlushLabels() { + if (window.confirm('Flush all external (automation and channel) labels?')) { + this.props.dispatch(flushExtLabels()) + this.props.dispatch(storeFlushChLabels()) + window.socketIoClient.emit(SOCKET_FLUSH_LABELS) + } + } + + handleClose = () => { + // window.socketIoClient.emit(SOCKET_GET_PAGES_LIST) + this.props.dispatch(storeShowLabelSetup()) + } + + handleCancel = () => { + // window.socketIoClient.emit(SOCKET_GET_PAGES_LIST) + this.props.dispatch(storeShowLabelSetup()) + } + + handleSave = () => { + this.props.dispatch(updateLabels(this.state.mutations)) + this.props.dispatch(storeShowLabelSetup()) + window.socketIoClient.emit(SOCKET_SET_LABELS, { update: this.state.mutations }) + } + + renderLabelList() { + return ( +
    + {this.props.fader.map((fader: IFader, index: number) => { + const faderLabel = fader.label || '-' + const channelLabel = getChannelLabel(window.reduxState, index) || '-' + const mutated = this.state.mutations[index] + + return ( + + +
    +
    + ) + })} +
    + ) + } + + render() { + return ( +
    +

    CUSTOM LABELS

    + + {this.renderLabelList()} + + +
    + + +
    + ) + } +} + +const mapStateToProps = (state: any, props: any): ILabelSettingsInjectProps => { + return { + customPages: state.settings[0].customPages, + fader: state.faders[0].fader, + } +} + +export default connect(mapStateToProps)( + LabelSettings +) as any diff --git a/client/src/components/MicTally.tsx b/client/src/components/MicTally.tsx new file mode 100644 index 00000000..2f14e184 --- /dev/null +++ b/client/src/components/MicTally.tsx @@ -0,0 +1,124 @@ +import * as React from 'react' +import { connect } from 'react-redux' + +import '../assets/css/MicTally.css' +import { Store } from 'redux' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { IChannels } from '../../../shared/src/reducers/channelsReducer' +import { ISettings } from '../../../shared/src/reducers/settingsReducer' +import { getFaderLabel } from '../utils/labels' + +import { + SOCKET_TOGGLE_PGM, + SOCKET_TOGGLE_VO, +} from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' + + +interface IMicTallyInjectProps { + channels: IChannels + faders: IFader[] + settings: ISettings +} + +interface IMicTallyState { + toggleTargetIndex: number | null +} + +class MicTally extends React.Component { + constructor(props: any) { + super(props) + this.props.settings.showMonitorOptions = -1 + this.state = { + toggleTargetIndex: null + } + } + + componentWillMount() { + document.body.classList.add('v-mic-tally') + } + + componentWillUnmount() { + document.body.classList.remove('v-mic-tally') + } + + preToggleFader(index: number) { + const fader = this.props.faders[index] + if (!fader || fader.muteOn) { + return + } + this.setState({ toggleTargetIndex: index }) + } + clearToggleFaderIndex() { + this.setState({ toggleTargetIndex: null }) + } + + toggleFader(index: number) { + const fader = this.props.faders[index] + const faderLabel = getFaderLabel(index) + + if (fader.muteOn) { + return + } + + if (fader.voOn) { + window.socketIoClient.emit(SOCKET_TOGGLE_VO, index) + } else { + window.socketIoClient.emit(SOCKET_TOGGLE_PGM, index) + } + this.clearToggleFaderIndex() + } + + faderIsOn(index: number) { + const fader = this.props.faders[index] + return Boolean(fader && (fader.pgmOn || fader.voOn) && !fader.muteOn) + } + + render() { + const hasToggleTargetIndex = this.state.toggleTargetIndex !== null + return ( +
    +
      + { this.props.faders + .map((fader, index) => { + if (!fader.showInMiniMonitor) { + return + } + const isOn = this.faderIsOn(index) + return ( +
    • +
      this.preToggleFader(index)} className={`c-mic-tally__status${isOn ? ' on': ''}${fader.muteOn ? ' muted' : ''}`}> +
      + { isOn ? 'ON' : 'OFF' } +
      +
      + {getFaderLabel(index)} +
    • + ) + }) + } +
    +
    +
    +

    Are you sure you want to turn '{ getFaderLabel(this.state.toggleTargetIndex) }' {this.faderIsOn(this.state.toggleTargetIndex) ? 'OFF' : 'ON'}?

    +
    + + +
    +
    +
    +
    + ) + } +} + +const mapStateToProps = (state: any): IMicTallyInjectProps => { + return { + channels: state.channels[0].chMixerConnection[0].channel, + faders: state.faders[0].fader, + settings: state.settings[0], + } +} + +export default connect(mapStateToProps)( + MicTally +) diff --git a/client/src/components/MiniChanStrip.tsx b/client/src/components/MiniChanStrip.tsx new file mode 100644 index 00000000..c3e9be65 --- /dev/null +++ b/client/src/components/MiniChanStrip.tsx @@ -0,0 +1,127 @@ +import React from 'react' +import ReactSlider from 'react-slider' + +import '../assets/css/MiniChanStrip.css' +import { Store } from 'redux' +import { connect } from 'react-redux' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { SOCKET_SET_AUX_LEVEL } from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import { getFaderLabel } from '../utils/labels' + +interface IChanStripInjectProps { + label: string + selectedProtocol: string + numberOfChannelsInType: Array + channel: Array + fader: Array + auxSendIndex: number + offtubeMode: boolean +} + +interface IChanStripProps { + faderIndex: number +} + +class MiniChanStrip extends React.PureComponent< + IChanStripProps & IChanStripInjectProps & Store +> { + constructor(props: any) { + super(props) + } + + handleMonitorLevel(event: any, channelIndex: number) { + window.socketIoClient.emit(SOCKET_SET_AUX_LEVEL, { + channel: channelIndex, + auxIndex: this.props.auxSendIndex, + level: parseFloat(event), + }) + } + + monitor(channelIndex: number) { + let faderIndex = this.props.channel[channelIndex].assignedFader + if (faderIndex === -1) return null + let monitorName = getFaderLabel(faderIndex, 'Fader') + return ( +
  • + {monitorName} + { + this.handleMonitorLevel(event, channelIndex) + }} + /> +

    _______

    +
  • + ) + } + parameters() { + return ( +
    +
    + {this.props.label || 'FADER ' + (this.props.faderIndex + 1)} + {' - MONITOR MIX MINUS'} +
    +
      + {this.props.channel.map((ch: any, index: number) => { + if (ch.auxLevel[this.props.auxSendIndex] >= 0) { + return this.monitor(index) + } + })} +
    +
    + ) + } + + render() { + if (this.props.faderIndex >= 0) { + return ( +
    + {this.props.offtubeMode ? this.parameters() : null} +
    + ) + } else { + return
    + } + } +} + +const mapStateToProps = (state: any, props: any): IChanStripInjectProps => { + let inject: IChanStripInjectProps = { + label: '', + selectedProtocol: state.settings[0].mixers[0].mixerProtocol, + numberOfChannelsInType: + state.settings[0].mixers[0].numberOfChannelsInType, + channel: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader, + auxSendIndex: -1, + offtubeMode: state.settings[0].offtubeMode, + } + if (props.faderIndex >= 0) { + inject = { + label: getFaderLabel(props.faderIndex), + selectedProtocol: state.settings[0].mixers[0].mixerProtocol, + numberOfChannelsInType: + state.settings[0].mixers[0].numberOfChannelsInType, + channel: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader, + auxSendIndex: state.faders[0].fader[props.faderIndex].monitor - 1, + offtubeMode: state.settings[0].offtubeMode, + } + } + return inject +} + +export default connect(mapStateToProps)( + MiniChanStrip +) as any diff --git a/client/src/components/MiniChannel.tsx b/client/src/components/MiniChannel.tsx new file mode 100644 index 00000000..7216242d --- /dev/null +++ b/client/src/components/MiniChannel.tsx @@ -0,0 +1,94 @@ +import * as React from 'react' +import ClassNames from 'classnames' +import { connect } from 'react-redux' +import { Store } from 'redux' +import '../assets/css/NoUiSlider.css' + +//assets: +import '../assets/css/MiniChannel.css' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { IChannels } from '../../../shared/src/reducers/channelsReducer' +import { ISettings } from '../../../shared/src/reducers/settingsReducer' +import { storeShowChanStrip } from '../../../shared/src/actions/settingsActions' +import { getFaderLabel } from '../utils/labels' + +interface IChannelInjectProps { + channels: IChannels + fader: IFader + settings: ISettings + channelType: number + channelTypeIndex: number + label: string +} + +interface IChannelProps { + faderIndex: number +} + +class MiniChannel extends React.Component< + IChannelProps & IChannelInjectProps & Store +> { + faderIndex: number + + constructor(props: any) { + super(props) + this.faderIndex = this.props.faderIndex + } + + public shouldComponentUpdate(nextProps: IChannelInjectProps) { + return ( + nextProps.fader.showChannel != this.props.fader.showChannel || + nextProps.label != this.props.label || + nextProps.settings.showChanStrip != + this.props.settings.showChanStrip + ) + } + + handleShowChanStrip() { + this.props.dispatch(storeShowChanStrip(this.faderIndex)) + } + + chanStripButton = () => { + return ( + + ) + } + + render() { + return this.props.fader.showChannel === false ? null : ( +
    + + {this.chanStripButton()} +
    +
    +
    + ) + } +} + +const mapStateToProps = (state: any, props: any): IChannelInjectProps => { + return { + channels: state.channels[0].chMixerConnection[0].channel, + fader: state.faders[0].fader[props.faderIndex], + settings: state.settings[0], + channelType: 0 /* TODO: state.channels[0].channel[props.channelIndex].channelType, */, + channelTypeIndex: + props.faderIndex /* TODO: state.channels[0].chMixerConnection[0].channel[props.channelIndex].channelTypeIndex, */, + label: getFaderLabel(props.faderIndex) + } +} + +export default connect(mapStateToProps)( + MiniChannel +) as any diff --git a/client/src/components/MiniChannels.tsx b/client/src/components/MiniChannels.tsx new file mode 100644 index 00000000..42e5f376 --- /dev/null +++ b/client/src/components/MiniChannels.tsx @@ -0,0 +1,74 @@ +import * as React from 'react' +import { connect } from 'react-redux' + +import '../assets/css/MiniChannels.css' +import { Store } from 'redux' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { IChannels } from '../../../shared/src/reducers/channelsReducer' +import { ISettings } from '../../../shared/src/reducers/settingsReducer' +import MiniChannel from './MiniChannel' +import MiniChanStrip from './MiniChanStrip' + +interface IChannelsInjectProps { + channels: IChannels + faders: IFader[] + settings: ISettings +} + +class Channels extends React.Component { + constructor(props: any) { + super(props) + this.props.settings.showMonitorOptions = -1 + } + + public shouldComponentUpdate(nextProps: IChannelsInjectProps) { + return ( + this.props.settings.showOptions !== + nextProps.settings.showOptions || + this.props.settings.showChanStrip !== + nextProps.settings.showChanStrip || + this.props.settings.showMonitorOptions !== + nextProps.settings.showMonitorOptions || + this.props.settings.mixers[0].mixerOnline !== + nextProps.settings.mixers[0].mixerOnline || + this.props.faders.length !== nextProps.faders.length + ) + } + + render() { + return ( +
    + {this.props.faders.map((fader: IFader, index: number) => { + return fader.showInMiniMonitor ? ( + + ) : null + })} + {this.props.settings.showChanStrip >= 0 ? ( +
    + +
    + ) : ( +
    + +
    + )} +
    + ) + } +} + +const mapStateToProps = (state: any): IChannelsInjectProps => { + return { + channels: state.channels[0].chMixerConnection[0].channel, + faders: state.faders[0].fader, + settings: state.settings[0], + } +} + +export default connect(mapStateToProps)( + Channels +) diff --git a/client/src/components/PagesSettings.tsx b/client/src/components/PagesSettings.tsx new file mode 100644 index 00000000..9e9d22b8 --- /dev/null +++ b/client/src/components/PagesSettings.tsx @@ -0,0 +1,220 @@ +import React, { ChangeEvent } from 'react' +import ClassNames from 'classnames' + +import '../assets/css/PagesSettings.css' +import { Store } from 'redux' +import { connect } from 'react-redux' +import { + storeShowPagesSetup, + storeUpdatePagesList, +} from '../../../shared/src/actions/settingsActions' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import Select from 'react-select' +import { + SOCKET_GET_PAGES_LIST, + SOCKET_SET_PAGES_LIST, +} from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import { ICustomPages } from '../../../shared/src/reducers/settingsReducer' +import { getFaderLabel } from '../utils/labels' + +//Set style for Select dropdown component: +const selectorColorStyles = { + control: (styles: any) => ({ + ...styles, + backgroundColor: '#676767', + color: 'white', + border: 0, + width: 400, + }), + option: (styles: any) => { + return { + backgroundColor: '#AAAAAA', + color: 'white', + } + }, + singleValue: (styles: any) => ({ ...styles, color: 'white' }), +} +interface IPagesSettingsInjectProps { + customPages: ICustomPages[] + fader: IFader[] +} + +class PagesSettings extends React.PureComponent< + IPagesSettingsInjectProps & Store +> { + pageList: { label: string; value: number }[] + state = { pageIndex: 0, label: '' } + + constructor(props: any) { + super(props) + + this.pageList = this.props.customPages.map( + (page: ICustomPages, index: number) => { + return { label: page.label, value: index } + } + ) + } + + componentDidMount() { + this.setState({ label: this.props.customPages[0].label }) + } + + handleSelectPage(event: any) { + this.setState({ pageIndex: event.value }) + this.setState({ + label: this.props.customPages[event.value].label, + }) + console.log('PAGE SELECTED', this.state.pageIndex) + } + + handleAssignFader(fader: number, event: any) { + if (event.target.checked === false) { + console.log('Unbinding Fader') + if ( + window.confirm( + 'Unbind Fader from page ' + + String(fader + 1) + + ' from Page ' + + String(this.state.pageIndex + 1) + ) + ) { + let nextPages: ICustomPages[] = [...this.props.customPages] + nextPages[this.state.pageIndex].faders.splice( + this.props.customPages[this.state.pageIndex].faders.indexOf( + fader + ), + 1 + ) + window.storeRedux.dispatch(storeUpdatePagesList(nextPages)) + window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages) + } + } else { + console.log('Binding Channel') + if ( + window.confirm( + 'Bind Fader ' + + String(fader + 1) + + ' to Page ' + + String(this.state.pageIndex + 1) + + '?' + ) + ) { + let nextPages: ICustomPages[] = [...this.props.customPages] + nextPages[this.state.pageIndex].faders.push(fader) + nextPages[this.state.pageIndex].faders.sort((a, b) => { + return a - b + }) + window.storeRedux.dispatch(storeUpdatePagesList(nextPages)) + window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages) + } + } + } + + handleLabel = (event: ChangeEvent) => { + this.setState({ label: event.target.value }) + this.pageList[this.state.pageIndex].label = event.target.value + let nextPages: ICustomPages[] = [...this.props.customPages] + nextPages[this.state.pageIndex].label = event.target.value + + window.storeRedux.dispatch(storeUpdatePagesList(nextPages)) + window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages) + } + + handleClearRouting() { + if (window.confirm('REMOVE ALL FADER ASSIGNMENTS????')) { + let nextPages: ICustomPages[] = [...this.props.customPages] + nextPages[this.state.pageIndex].faders = [] + window.storeRedux.dispatch(storeUpdatePagesList(nextPages)) + window.socketIoClient.emit(SOCKET_SET_PAGES_LIST, nextPages) + } + } + + handleClose = () => { + window.socketIoClient.emit(SOCKET_GET_PAGES_LIST) + this.props.dispatch(storeShowPagesSetup()) + } + + renderFaderList() { + return ( +
    + {this.props.fader.map((fader: IFader, index: number) => { + return ( +
    + {' Fader ' + (index + 1) + ' - ' + getFaderLabel(index) + ' : '} + {} + + this.handleAssignFader(index, event) + } + /> + +
    + ) + })} +
    + ) + } + + render() { + return ( +
    +

    CUSTOM PAGES

    + + this.handleLabel(event)} + /> + +
    + {this.renderFaderList()} + +
    +
    + ) + } +} + +const mapStateToProps = (state: any, props: any): IPagesSettingsInjectProps => { + return { + customPages: state.settings[0].customPages, + fader: state.faders[0].fader, + } +} + +export default connect(mapStateToProps)( + PagesSettings +) as any diff --git a/client/src/components/ReductionMeter.tsx b/client/src/components/ReductionMeter.tsx new file mode 100644 index 00000000..30c62c30 --- /dev/null +++ b/client/src/components/ReductionMeter.tsx @@ -0,0 +1,194 @@ +import * as React from 'react' +import { connect } from 'react-redux' + +//assets: +import '../assets/css/ReductionMeter.css' +//Utils: + +export interface IReductionMeterInjectedProps { + reductionVal: number +} + +interface IVuMeterProps { + faderIndex: number +} + +export class ReductionMeter extends React.Component { + canvas: HTMLCanvasElement | undefined + + totalPeak: number = 0 + windowPeak: number = 0 + windowLast: number = 0 + meterMax: number = 1 + meterMin: number = 0 + meterTest: number = 0.75 + meterZero: number = 0.75 + WINDOW: number = 2000 + + constructor(props: any) { + super(props) + this.meterMax = window.mixerProtocol.meter?.max || 1 + this.meterMin = window.mixerProtocol.meter?.min || 0 + this.meterTest = window.mixerProtocol.meter?.test || 0.75 + this.meterZero = window.mixerProtocol.meter?.zero || 0.75 + } + + public shouldComponentUpdate(nextProps: IReductionMeterInjectedProps) { + return nextProps.reductionVal != this.props.reductionVal + } + + totalHeight = () => { + return 170 / (this.meterMax - this.meterMin) + } + + getTotalPeak = () => { + if (this.props.reductionVal > this.totalPeak) { + this.totalPeak = this.props.reductionVal + } + return this.totalHeight() * this.totalPeak + } + + getWindowPeak = () => { + if ( + this.props.reductionVal > this.windowPeak || + Date.now() - this.windowLast > this.WINDOW + ) { + this.windowPeak = this.props.reductionVal + this.windowLast = Date.now() + } + return this.totalHeight() * this.windowPeak + } + + calcLower = () => { + let val = this.props.reductionVal + if (val >= this.meterTest) { + val = this.meterTest + } + return this.totalHeight() * val + } + + calcMiddle = () => { + let val = this.props.reductionVal + if (val < this.meterTest) { + val = 0 + } else if (val >= this.meterZero) { + val = this.meterZero - this.meterTest + } else { + val = this.props.reductionVal - this.meterTest + } + return this.totalHeight() * val + 1 + } + + calcUpper = () => { + let val = this.props.reductionVal + if (val < this.meterZero) { + val = 0 + } else { + val = this.props.reductionVal - this.meterZero + } + + return this.totalHeight() * val + 1 + } + + setRef = (element: HTMLCanvasElement) => { + this.canvas = element + + this.paintVuMeter() + } + + resetTotalPeak = () => { + this.totalPeak = 0 + } + + paintVuMeter = () => { + if (!this.canvas) return + + const context = this.canvas.getContext('2d', { + antialias: false, + stencil: false, + preserveDrawingBuffer: true, + }) as CanvasRenderingContext2D + + if (!context) return + + context.clearRect( + 0, + 0, + this.canvas.clientWidth, + this.canvas.clientHeight + ) + + // lower part + context.fillStyle = 'rgb(0, 122, 37)' + context.fillRect(0, 0, this.canvas.clientWidth, this.calcLower()) //(this.totalHeight() - this.calcLower()), this.canvas.clientWidth, this.calcLower()) + + // middle part + let middle = this.calcMiddle() + let middleRef = this.totalHeight() * this.meterTest + context.fillStyle = 'rgb(53, 167, 0)' + context.fillRect(0, middleRef, this.canvas.clientWidth, middle) // (this.totalHeight() * (range - this.meterTest) - this.calcMiddle()), this.canvas.clientWidth, this.calcMiddle()) + + // upper part (too high/clip) + let upper = this.calcUpper() + let upperRef = this.totalHeight() * this.meterZero + context.fillStyle = 'rgb(206, 0, 0)' + context.fillRect(0, upperRef, this.canvas.clientWidth, upper) + + // windowed peak + const windowPeak = this.getWindowPeak() + if (this.windowPeak < this.meterZero) { + context.fillStyle = 'rgb(16, 56, 0)' + } else { + context.fillStyle = 'rgb(100, 100, 100)' + } + context.fillRect(0, windowPeak, this.canvas.clientWidth, 2) + + // absolute peak + if (this.totalPeak < this.meterZero) { + context.fillStyle = 'rgb(64, 64, 64)' + } else { + context.fillStyle = 'rgb(255, 0, 0)' + } + context.fillRect(0, this.getTotalPeak(), this.canvas.clientWidth, 2) + } + + render() { + this.paintVuMeter() + + return ( +
    + +

    ___6dB

    +

    12dB

    +
    + ) + } +} + +const mapStateToProps = ( + state: any, + props: any +): IReductionMeterInjectedProps => { + return { + reductionVal: state.faders[0].vuMeters[props.faderIndex].reductionVal, + } +} + +export default connect(mapStateToProps)( + ReductionMeter +) diff --git a/client/src/components/RoutingStorage.tsx b/client/src/components/RoutingStorage.tsx new file mode 100644 index 00000000..cc619cbb --- /dev/null +++ b/client/src/components/RoutingStorage.tsx @@ -0,0 +1,187 @@ +import React from 'react' + +import '../assets/css/RoutingStorage.css' +import { Store } from 'redux' +import { connect } from 'react-redux' +import { TOGGLE_SHOW_STORAGE } from '../../../shared/src/actions/settingsActions' +import { + SOCKET_GET_SNAPSHOT_LIST, + SOCKET_LOAD_SNAPSHOT, + SOCKET_SAVE_SNAPSHOT, + SOCKET_GET_CCG_LIST, + SOCKET_SAVE_CCG_FILE, + SOCKET_GET_MIXER_PRESET_LIST, + SOCKET_LOAD_MIXER_PRESET, +} from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' + +interface IStorageProps { + load: any + save: any +} +class Storage extends React.PureComponent { + fileList: string[] = [] + loadSnapshot: any + saveSnapshot: any + + constructor(props: any) { + super(props) + this.loadSnapshot = this.props.load + this.saveSnapshot = this.props.save + + //Bindings: + this.ListSnapshotFiles = this.ListSnapshotFiles.bind(this) + this.ListCcgFiles = this.ListCcgFiles.bind(this) + this.ListPresetFiles = this.ListPresetFiles.bind(this) + this.loadMixerPreset = this.loadMixerPreset.bind(this) + this.loadFile = this.loadFile.bind(this) + this.saveFile = this.saveFile.bind(this) + } + + handleClose = () => { + this.props.dispatch({ + type: TOGGLE_SHOW_STORAGE, + }) + } + + saveFile() { + let fileName = window.prompt('Enter filename :', 'newfile') + if ( + window.confirm( + 'Are you sure you will save ' + + fileName + + ' as new routing setup?' + ) + ) { + console.log('Saving file') + window.socketIoClient.emit(SOCKET_SAVE_SNAPSHOT, fileName + '.shot') + } + this.handleClose() + } + + loadFile(event: any) { + if (window.confirm('Are you sure you will load a new routing setup?')) { + console.log('Loading files') + window.socketIoClient.emit( + SOCKET_LOAD_SNAPSHOT, + event.target.textContent + ) + } + this.handleClose() + } + + loadCcgFile(event: any) { + if (window.confirm('Are you sure you will load a CasparCG setup?')) { + console.log('Setting default CasparCG file') + window.socketIoClient.emit( + SOCKET_SAVE_CCG_FILE, + event.target.textContent + ) + } + this.handleClose() + } + + loadMixerPreset(event: any) { + if (window.confirm('Are you sure you will load a full Mixer setup?')) { + console.log('Loading Mixer preset') + window.socketIoClient.emit( + SOCKET_LOAD_MIXER_PRESET, + event.target.textContent + ) + } + this.handleClose() + } + + ListSnapshotFiles() { + window.socketIoClient.emit(SOCKET_GET_SNAPSHOT_LIST) + const listItems = window.snapshotFileList.map( + (file: string, index: number) => { + return ( +
  • + {file} +
  • + ) + } + ) + return
      {listItems}
    + } + + ListCcgFiles() { + window.socketIoClient.emit(SOCKET_GET_CCG_LIST) + const listItems = window.ccgFileList.map( + (file: string, index: number) => { + return ( +
  • + {file} +
  • + ) + } + ) + return
      {listItems}
    + } + + ListPresetFiles() { + window.socketIoClient.emit(SOCKET_GET_MIXER_PRESET_LIST) + const listItems = window.mixerPresetList.map( + (file: string, index: number) => { + return ( +
  • + {file} +
  • + ) + } + ) + return
      {listItems}
    + } + + render() { + return ( +
    + +

    STORAGE

    +
    + {window.location.search.includes('settings=1') ? ( + +

    SAVE ROUTING :

    + +
    +

    LOAD ROUTING :

    + +
    + ) : null} + {window.mixerPresetList.length > 0 ? ( + +
    +
    +

    LOAD MIXER PRESET :

    + +
    + ) : null} + {window.ccgFileList.length > 0 ? ( + +
    +
    +

    LOAD CASPARCG :

    + +
    + ) : null} +
    + ) + } +} + +const mapStateToProps = (state: any, props: any): any => { + return { + load: props.load, + save: props.save, + } +} + +export default connect(mapStateToProps)(Storage) as any diff --git a/client/src/components/Settings.tsx b/client/src/components/Settings.tsx new file mode 100644 index 00000000..c4e392b0 --- /dev/null +++ b/client/src/components/Settings.tsx @@ -0,0 +1,576 @@ +import * as React from 'react' +import { connect } from 'react-redux' +import Select from 'react-select' +import WebMidi from 'webmidi' +import { IAppProps } from './App' + +//Utils: +import '../assets/css/Settings.css' +import { ISettings } from '../../../shared/src/reducers/settingsReducer' +import { Store } from 'redux' +import { ChangeEvent } from 'react' +import { SOCKET_SAVE_SETTINGS } from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import { storeShowSettings } from '../../../shared/src/actions/settingsActions' + +//Set style for Select dropdown component: +const selectorColorStyles = { + control: (styles: any) => ({ + ...styles, + backgroundColor: '#676767', + color: 'white', + border: 0, + width: 500, + marginLeft: 100, + }), + option: (styles: any) => { + return { + backgroundColor: '#AAAAAA', + color: 'white', + } + }, + singleValue: (styles: any) => ({ ...styles, color: 'white' }), +} + +interface IState { + settings: ISettings +} + +class Settings extends React.PureComponent { + selectedProtocol: any + midiInputPortList: any + midiOutputPortList: any + + constructor(props: any) { + super(props) + + this.state = { + settings: this.props.store.settings[0], + } + //Initialise list of Midi ports: + this.findMidiPorts() + } + + findMidiPorts = () => { + WebMidi.enable((err) => { + if (err) { + console.log('WebMidi could not be enabled.', err) + } + + // Viewing available inputs and outputs + console.log('Midi inputs : ', WebMidi.inputs) + console.log('Midi outputs : ', WebMidi.outputs) + }) + this.midiInputPortList = WebMidi.inputs.map((input) => { + return { label: input.name, value: input.name } + }) + this.midiOutputPortList = WebMidi.outputs.map((output) => { + return { label: output.name, value: output.name } + }) + } + + handleRemoteMidiInputPort = (selectedOption: any) => { + let settingsCopy = Object.assign({}, this.state.settings) + settingsCopy.remoteFaderMidiInputPort = selectedOption.value + this.setState({ settings: settingsCopy }) + } + + handleRemoteMidiOutputPort = (selectedOption: any) => { + let settingsCopy = Object.assign({}, this.state.settings) + settingsCopy.remoteFaderMidiOutputPort = selectedOption.value + this.setState({ settings: settingsCopy }) + } + + handleMixerMidiInputPort = (selectedOption: any) => { + let settingsCopy = Object.assign({}, this.state.settings) + settingsCopy.mixers[0].mixerMidiInputPort = selectedOption.value + this.setState({ settings: settingsCopy }) + } + + handleMixerMidiOutputPort = (selectedOption: any) => { + let settingsCopy = Object.assign({}, this.state.settings) + settingsCopy.mixers[0].mixerMidiOutputPort = selectedOption.value + this.setState({ settings: settingsCopy }) + } + + handleChange = (event: ChangeEvent) => { + let settingsCopy = Object.assign({}, this.state.settings) + if (event.target.type === 'checkbox') { + ;(settingsCopy as any)[event.target.name] = !!(event.target as HTMLInputElement).checked + } else { + ;(settingsCopy as any)[event.target.name] = event.target.value + } + this.setState({ settings: settingsCopy }) + } + + handleNumberOfMixers = (event: ChangeEvent) => { + let settingsCopy = Object.assign({}, this.state.settings) + settingsCopy.numberOfMixers = parseInt(event.target.value) || 1 + settingsCopy = this.setNumberOfMixers(settingsCopy) + this.setState({ settings: settingsCopy }) + } + + setNumberOfMixers = (settings: any) => { + console.log(settings.mixers) + let mixers = settings.mixers.map((mixer: any, index: number) => { + if (index < settings.numberOfMixers) { + return mixer + } + }) + + settings.mixers = [] + for (let i = 0; i < settings.numberOfMixers; i++) { + if (settings.mixers[i] === undefined) { + settings.mixers.push(JSON.parse(JSON.stringify(mixers[0]))) + } else { + settings.mixers.push(mixers[i]) + } + } + return settings + } + + handleMixerChange = ( + event: ChangeEvent, + mixerIndex: number + ) => { + let settingsCopy = Object.assign({}, this.state.settings) + if (event.target.type === 'checkbox') { + ;(settingsCopy.mixers[mixerIndex] as any)[ + event.target.name + ] = !!event.target.checked + } else { + ;(settingsCopy.mixers[mixerIndex] as any)[event.target.name] = + event.target.value + } + this.setState({ settings: settingsCopy }) + } + + handleProtocolChange = (selectedOption: any, mixerIndex: number) => { + let settingsCopy = Object.assign({}, this.state.settings) + settingsCopy.mixers[mixerIndex].mixerProtocol = selectedOption.value + window.mixerProtocol = + window.mixerProtocolPresets[ + settingsCopy.mixers[mixerIndex].mixerProtocol + ] + this.setState({ settings: settingsCopy }) + } + + handleNumberOfChannels = ( + mixerIndex: number, + index: number, + event: any + ) => { + let settingsCopy = Object.assign({}, this.state.settings) + settingsCopy.mixers[mixerIndex].numberOfChannelsInType[index] = + parseInt(event.target.value) || 1 + this.setState({ settings: settingsCopy }) + } + + handleSave = () => { + let settingsCopy = Object.assign({}, this.state.settings) + settingsCopy.showSettings = false + window.socketIoClient.emit(SOCKET_SAVE_SETTINGS, settingsCopy) + this.props.dispatch(storeShowSettings()) + window.alert( + 'restarting Sisyfos' + ) + setTimeout(()=> { + location.reload() + }, 2000) + } + + handleCancel = () => { + this.props.dispatch(storeShowSettings()) + } + + renderChannelTypeSettings = (mixerIndex: number) => { + return ( +
    + {window.mixerProtocolPresets[ + this.state.settings.mixers[mixerIndex].mixerProtocol + ].channelTypes.map((item: any, index: number) => { + return ( + + +
    +
    + ) + })} +
    + ) + } + + renderMixerMidiSettings = () => { + return ( +
    +
    MIXER MIDI SETTINGS:
    +
    + Mixer Midi Input Port : +
    + +
    +
    + ) + } + + renderMixerSettings = () => { + return ( +
    + {this.state.settings.mixers.map( + (mixer: any, mixerIndex: number) => { + return ( + +
    + MIXER {mixerIndex + 1} SETTINGS: +
    + + + this.handleMixerChange( + event, + mixerIndex + ) + } + /> + +
    + +
    + +
    + +
    + +
    + +
    + +
    + {window.mixerProtocol.protocol === 'MIDI' + ? this.renderMixerMidiSettings() + : ''} +
    + {this.renderChannelTypeSettings(mixerIndex)} +
    +
    + ) + } + )} +
    + ) + } + + render() { + return ( +
    +
    GENERIC SETTINGS
    +
    Sisyfos v.{this.state.settings.sisyfosVersion}
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + + {this.renderMixerSettings()} + + +
    + ) + } +} + +const mapStateToProps = (state: any, t: any): IAppProps => { + return { + store: state, + t: t, + } +} + +export default connect(mapStateToProps)(Settings) as any diff --git a/client/src/components/VuMeter.tsx b/client/src/components/VuMeter.tsx new file mode 100644 index 00000000..66a7164d --- /dev/null +++ b/client/src/components/VuMeter.tsx @@ -0,0 +1,229 @@ +import * as React from 'react' +import { connect } from 'react-redux' +import { vuMeters } from '../utils/SocketClientHandlers' + +//assets: +import '../assets/css/VuMeter.css' +//Utils: + +export interface IVuMeterInjectedProps { + faderIndex: number + channel: number +} + +interface IVuMeterProps { + faderIndex: number +} + +export class VuMeter extends React.PureComponent { + canvas: HTMLCanvasElement | undefined + + totalPeak: number = 0 + windowPeak: number = 0 + windowLast: number = 0 + meterMax: number = 1 + meterMin: number = 0 + meterTest: number = 0.75 + meterZero: number = 0.75 + WINDOW: number = 2000 + + private _painting = false + private _previousVal = -1 + private _value = 0 + + constructor(props: any) { + super(props) + this.meterMax = window.mixerProtocol.meter?.max || 1 + this.meterMin = window.mixerProtocol.meter?.min || 0 + this.meterTest = window.mixerProtocol.meter?.test || 0.75 + this.meterZero = window.mixerProtocol.meter?.zero || 0.75 + } + + componentDidMount() { + if (this._painting) this.paintVuMeter() + } + + totalHeight = () => { + return ( + (400) / + (this.meterMax - this.meterMin) + ) + } + + getTotalPeak = () => { + if (this._value > this.totalPeak) { + this.totalPeak = this._value + } + return this.totalHeight() * this.totalPeak + } + + getWindowPeak = () => { + if ( + this._value > this.windowPeak || + Date.now() - this.windowLast > this.WINDOW + ) { + this.windowPeak = this._value + this.windowLast = Date.now() + } + return this.totalHeight() * this.windowPeak + } + + calcLower = () => { + let val = this._value + if (val >= this.meterTest) { + val = this.meterTest + } + return this.totalHeight() * val + } + + calcMiddle = () => { + let val = this._value + if (val < this.meterTest) { + val = this.meterTest + } else if (val >= this.meterZero) { + val = this.meterZero + } + return this.totalHeight() * (val - this.meterTest) + 1 + } + + calcUpper = () => { + let val = this._value + if (val < this.meterZero) { + val = this.meterZero + } + return this.totalHeight() * (val - this.meterZero) + 1 + } + + setRef = (el: HTMLCanvasElement) => { + this.canvas = el + + this.paintVuMeter() + } + + resetTotalPeak = () => { + this.totalPeak = 0 + } + + paintVuMeter = () => { + if (!this.canvas) { + this._painting = false + return + } + this._painting = true + + this._value = vuMeters[this.props.faderIndex]?.[this.props.channel] || 0 + + if (this._value === this._previousVal) { + this._painting = false + window.requestAnimationFrame(this.paintVuMeter) + return + } + this._previousVal = this._value + + const context = this.canvas.getContext('2d', { + antialias: false, + stencil: false, + preserveDrawingBuffer: true, + }) as CanvasRenderingContext2D + + if (!context) return + + const range = this.meterMax - this.meterMin + context.clearRect( + 0, + 0, + this.canvas.clientWidth, + this.canvas.clientHeight + ) + + // lower part + context.fillStyle = 'rgb(0, 122, 37)' + context.fillRect( + 0, + this.totalHeight() - this.calcLower(), + this.canvas.clientWidth, + this.calcLower() + ) + + // middle part + context.fillStyle = 'rgb(53, 167, 0)' + context.fillRect( + 0, + this.totalHeight() * (range - this.meterTest) - this.calcMiddle(), + this.canvas.clientWidth, + this.calcMiddle() + ) + + // upper part (too high/clip) + context.fillStyle = 'rgb(206, 0, 0)' + context.fillRect( + 0, + this.totalHeight() * (range - this.meterZero) - this.calcUpper(), + this.canvas.clientWidth, + this.calcUpper() + ) + + // windowed peak + const windowPeak = this.getWindowPeak() + if (this.windowPeak < this.meterZero) { + context.fillStyle = 'rgb(16, 56, 0)' + } else { + context.fillStyle = 'rgb(100, 100, 100)' + } + context.fillRect( + 0, + this.totalHeight() - windowPeak, + this.canvas.clientWidth, + 2 + ) + + // absolute peak + if (this.totalPeak < this.meterZero) { + context.fillStyle = 'rgb(64, 64, 64)' + } else { + context.fillStyle = 'rgb(255, 0, 0)' + } + context.fillRect( + 0, + this.totalHeight() - this.getTotalPeak(), + this.canvas.clientWidth, + 2 + ) + + window.requestAnimationFrame(this.paintVuMeter) + } + + render() { + return ( +
    + +
    + ) + } +} + +const mapStateToProps = (state: any, props: any): IVuMeterInjectedProps => { + return { + faderIndex: props.faderIndex, + channel: props.channel + } +} + +export default connect(mapStateToProps)( + VuMeter +) diff --git a/client/src/utils/SocketClientHandlers.ts b/client/src/utils/SocketClientHandlers.ts new file mode 100644 index 00000000..6beaebfd --- /dev/null +++ b/client/src/utils/SocketClientHandlers.ts @@ -0,0 +1,150 @@ +import { + storeSetCompleteFaderState, + storeSetSingleFaderState, + storeVuReductionLevel, +} from '../../../shared/src/actions/faderActions' +import { + storeSetCompleteChState, + storeSetSingleChState, +} from '../../../shared/src/actions/channelActions' +import { + storeSetMixerOnline, + storeSetServerOnline, + storeUpdatePagesList, + storeUpdateSettings, +} from '../../../shared/src/actions/settingsActions' +import { + SOCKET_RETURN_SNAPSHOT_LIST, + SOCKET_SET_FULL_STORE, + SOCKET_SET_STORE_FADER, + SOCKET_SET_STORE_CHANNEL, + SOCKET_RETURN_CCG_LIST, + SOCKET_SET_MIXER_ONLINE, + SOCKET_RETURN_MIXER_PRESET_LIST, + SOCKET_RETURN_PAGES_LIST, +} from '../../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import { + IchMixerConnection, + InumberOfChannels, +} from '../../../shared/src/reducers/channelsReducer' +import { VuType } from '../../../shared/src/utils/vu-server-types' +import { IMixerSettings } from '../../../shared/src/reducers/settingsReducer' + +export const vuMeters: number[][] = [] + +export const socketClientHandlers = () => { + window.socketIoClient + .on('connect', () => { + window.storeRedux.dispatch(storeSetServerOnline(true)) + console.log('CONNECTED TO SISYFOS SERVER') + if (!window.location.search.includes('vu=0')) { + // subscribe to VU' + window.socketIoClient.emit( + 'subscribe-vu-meter', + 'subscribe to vu meters' + ) + } + }) + .on('disconnect', () => { + window.storeRedux.dispatch(storeSetServerOnline(false)) + console.log('LOST CONNECTION TO SISYFOS SERVER') + }) + .on(SOCKET_SET_FULL_STORE, (payload: any) => { + // console.log('STATE RECEIVED :', payload) + if (window.mixerProtocol) { + let numberOfChannels: InumberOfChannels[] = [] + payload.channels[0].chMixerConnection.forEach( + ( + chMixerConnection: IchMixerConnection, + mixerIndex: number + ) => { + numberOfChannels.push({ numberOfTypeInCh: [] }) + numberOfChannels[mixerIndex].numberOfTypeInCh = [ + chMixerConnection.channel.length, + ] + } + ) + window.storeRedux.dispatch( + storeSetCompleteChState( + payload.channels[0], + numberOfChannels + ) + ) + window.storeRedux.dispatch( + storeSetCompleteFaderState( + payload.faders[0], + payload.settings[0].numberOfFaders + ) + ) + payload.settings[0].mixers.forEach( + (mixer: IMixerSettings, i: number) => { + window.storeRedux.dispatch( + storeSetMixerOnline(i, mixer.mixerOnline) + ) + } + ) + window.storeRedux.dispatch(storeSetServerOnline(true)) + } + }) + .on('set-settings', (payload: any) => { + // console.log('SETTINGS RECEIVED :', payload) + window.storeRedux.dispatch(storeUpdateSettings(payload)) + }) + .on('set-mixerprotocol', (payload: any) => { + // console.log('MIXERPROTOCOL RECEIVED :', payload) + window.mixerProtocol = payload.mixerProtocol + window.mixerProtocolPresets = payload.mixerProtocolPresets + window.mixerProtocolList = payload.mixerProtocolList + }) + .on(SOCKET_SET_MIXER_ONLINE, (payload: any) => { + window.storeRedux.dispatch( + storeSetMixerOnline(payload.mixerIndex, payload.mixerOnline) + ) + }) + .on(SOCKET_SET_STORE_FADER, (payload: any) => { + if ('faderIndex' in payload && 'state' in payload) { + window.storeRedux.dispatch( + storeSetSingleFaderState(payload.faderIndex, payload.state) + ) + } + }) + .on(SOCKET_SET_STORE_CHANNEL, (payload: any) => { + window.storeRedux.dispatch( + storeSetSingleChState(payload.channelIndex, payload.state) + ) + }) + .on(SOCKET_RETURN_SNAPSHOT_LIST, (payload: any) => { + window.snapshotFileList = payload + }) + .on(SOCKET_RETURN_CCG_LIST, (payload: any) => { + window.ccgFileList = payload + }) + .on(SOCKET_RETURN_MIXER_PRESET_LIST, (payload: any) => { + window.mixerPresetList = payload + }) + .on(SOCKET_RETURN_PAGES_LIST, (payload: any) => { + window.storeRedux.dispatch(storeUpdatePagesList(payload)) + }) + .on( + VuType.Channel, + (faderIndex: number, channelIndex: number, level: number) => { + if (!vuMeters[faderIndex]) vuMeters[faderIndex] = [] + vuMeters[faderIndex][channelIndex] = level + } + ) + .on( + VuType.Reduction, + (faderIndex: number, channelIndex: number, level: number) => { + if ( + window.reduxState.settings[0].showChanStrip === + faderIndex || + window.reduxState.settings[0].showChanStripFull === + faderIndex + ) { + window.storeRedux.dispatch( + storeVuReductionLevel(faderIndex, level) + ) + } + } + ) +} diff --git a/client/src/utils/i18n.ts b/client/src/utils/i18n.ts new file mode 100644 index 00000000..7d3a4097 --- /dev/null +++ b/client/src/utils/i18n.ts @@ -0,0 +1,53 @@ +import i18n from 'i18next' +import LanguageDetector from 'i18next-browser-languagedetector' + +i18n.use(LanguageDetector).init({ + resources: { + en: { + translations: { + 'TRYING TO CONNECT TO SISYFOS SERVER': + 'TRYING TO CONNECT TO SISYFOS SERVER', + VO: 'VO', + PFL: 'PFL', + 'CUE NEXT': 'CUE NEXT', + PST: 'PST', + 'SLOW FADE': 'SLOW FADE', + }, + }, + nn: { + translations: { + VO: 'STK', + }, + }, + nb: { + translations: { + VO: 'STK', + }, + }, + sv: { + translations: { + VO: 'VO', + }, + }, + }, + whitelist: ['en', 'nn', 'nb', 'sv'], + fallbackLng: 'en', + debug: true, + + // have a common namespace used around the full app + ns: ['translations'], + defaultNS: 'translations', + + keySeparator: false, // we use content as keys + + interpolation: { + escapeValue: false, // not needed for react!! + formatSeparator: ',', + }, + + react: { + wait: true, + }, +}) + +export default i18n diff --git a/client/src/utils/labels.ts b/client/src/utils/labels.ts new file mode 100644 index 00000000..d6e474bc --- /dev/null +++ b/client/src/utils/labels.ts @@ -0,0 +1,48 @@ +import { IStore } from '../../../shared/src/reducers/store' + +export function getChannelLabel( + state: IStore, + faderIndex: number +): string | undefined { + return state.channels[0].chMixerConnection + .flatMap((conn) => + conn.channel.map((ch) => ({ + assignedFader: ch.assignedFader, + label: ch.label, + })) + ) + .filter((ch) => ch.label && ch.label !== '') + .find((ch) => ch.assignedFader === faderIndex)?.label +} + +export function getFaderLabel(faderIndex: number, defaultName = 'CH'): string { + const state: IStore = window.reduxState + const automationLabel = + state.faders[0].fader[faderIndex] && + state.faders[0].fader[faderIndex].label !== '' + ? state.faders[0].fader[faderIndex].label + : undefined + const userLabel = + state.faders[0].fader[faderIndex] && + state.faders[0].fader[faderIndex].userLabel !== '' + ? state.faders[0].fader[faderIndex].userLabel + : undefined + const channelLabel = getChannelLabel(state, faderIndex) + + switch (state.settings[0].labelType) { + case 'automation': + return automationLabel || defaultName + ' ' + (faderIndex + 1) + case 'user': + return userLabel || defaultName + ' ' + (faderIndex + 1) + case 'channel': + return channelLabel || defaultName + ' ' + (faderIndex + 1) + case 'automatic': + default: + return ( + userLabel || + automationLabel || + channelLabel || + defaultName + ' ' + (faderIndex + 1) + ) + } +} diff --git a/client/tsconfig.json b/client/tsconfig.json new file mode 100644 index 00000000..59e4e977 --- /dev/null +++ b/client/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "esnext", + // Search under node_modules for non-relative imports. + "moduleResolution": "node", + // Process & infer types from .js files. + "allowJs": false, + // Don't emit; allow Babel to transform files. + "noEmit": false, + // Enable strictest settings like strictNullChecks & noImplicitAny. + "strict": false, + // Disallow features that require cross-file information for emit. + "isolatedModules": false, + // Import non-ES modules as default imports. + "esModuleInterop": true, + //Support for jsx. + "jsx": "react", + // Check for "any" while converting to TS this can be turned off. + "noImplicitAny": true, + "module": "commonjs", + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "outDir": "../dist" + }, + "include": ["../client", "../shared"], + "exclude": ["../**/node_modules/*", "../**/dist", "../**/*.spec.ts"] +} diff --git a/client/utils/SocketClientHandlers.ts b/client/utils/SocketClientHandlers.ts deleted file mode 100644 index 1733996c..00000000 --- a/client/utils/SocketClientHandlers.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { SET_COMPLETE_FADER_STATE, SET_VU_LEVEL, SET_SINGLE_FADER_STATE } from "../../server/reducers/faderActions"; -import { SET_COMPLETE_CH_STATE, SET_SINGLE_CH_STATE } from "../../server/reducers/channelActions"; -import { UPDATE_SETTINGS, SET_MIXER_ONLINE } from "../../server/reducers/settingsActions"; -import { SOCKET_SET_VU, SOCKET_RETURN_SNAPSHOT_LIST, SOCKET_SET_FULL_STORE, SOCKET_SET_STORE_FADER, SOCKET_SET_STORE_CHANNEL, SOCKET_RETURN_CCG_LIST } from "../../server/constants/SOCKET_IO_DISPATCHERS"; - -export const socketClientHandlers = () => { - window.socketIoClient - .on(SOCKET_SET_FULL_STORE, ( - (payload: any) => { - // console.log('STATE RECEIVED :', payload) - - let numberOfChannels: number[] = [] - if(window.mixerProtocol) { - window.mixerProtocol.channelTypes.forEach((item: any, index: number) => { - numberOfChannels.push(payload.settings[0].numberOfChannelsInType[index]); - }) - window.storeRedux.dispatch({ - type: SET_COMPLETE_CH_STATE, - allState: payload.channels[0], - numberOfTypeChannels: numberOfChannels - }) - window.storeRedux.dispatch({ - type:SET_COMPLETE_FADER_STATE, - allState: payload.faders[0], - numberOfTypeChannels: payload.settings[0].numberOfFaders - }) - window.storeRedux.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: payload.settings[0].mixerOnline - }) - - } - - }) - ) - .on('set-settings', ( - (payload: any) => { - // console.log('SETTINGS RECEIVED :', payload) - window.storeRedux.dispatch({ - type: UPDATE_SETTINGS, - settings: payload // loadSettings(storeRedux.getState()) - }); - }) - ) - .on('set-mixerprotocol', ( - (payload: any) => { - // console.log('MIXERPROTOCOL RECEIVED :', payload) - window.mixerProtocol = payload.mixerProtocol - window.mixerProtocolPresets = payload.mixerProtocolPresets - window.mixerProtocolList = payload.mixerProtocolList - }) - ) - .on(SOCKET_SET_STORE_FADER, ( - (payload: any) => { - window.storeRedux.dispatch({ - type:SET_SINGLE_FADER_STATE, - faderIndex: payload.faderIndex, - state: payload.state - }); - }) - ) - .on(SOCKET_SET_STORE_CHANNEL, ( - (payload: any) => { - window.storeRedux.dispatch({ - type:SET_SINGLE_CH_STATE, - channelIndex: payload.channelIndex, - state: payload.state - }); - }) - ) - .on(SOCKET_SET_VU, ( - (payload: any) => { - window.storeRedux.dispatch({ - type:SET_VU_LEVEL, - channel: payload.faderIndex, - level: payload.level - }); - }) - ) - .on(SOCKET_RETURN_SNAPSHOT_LIST, ( - (payload: any) => { - window.snapshotFileList = payload - }) - ) - .on(SOCKET_RETURN_CCG_LIST, ( - (payload: any) => { - window.ccgFileList = payload - }) - ) - -} \ No newline at end of file diff --git a/client/webpack.config.js b/client/webpack.config.js new file mode 100644 index 00000000..33e859ea --- /dev/null +++ b/client/webpack.config.js @@ -0,0 +1,68 @@ +const webpack = require('webpack') +const path = require('path') +const HtmlWebpackPlugin = require('html-webpack-plugin') + +// Any directories you will be adding code/files into, need to be added to this array so webpack will pick them up +const defaultInclude = [ + path.resolve(__dirname, '../client'), + path.resolve(__dirname, '../shared'), +] + +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }, + { + test: /\.tsx?$/, + loader: 'ts-loader', + options: { + configFile: 'tsconfig.json', + }, + }, + { + test: /\.(jpe?g|png|gif)$/, + use: [ + { + loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]', + }, + ], + include: defaultInclude, + }, + { + test: /\.(eot|svg|ttf|woff|woff2)$/, + use: [ + { + loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]', + }, + ], + include: defaultInclude, + }, + ], + }, + entry: '.', + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + target: 'web', + output: { + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new HtmlWebpackPlugin({ + template: './index.ejs', + inject: true, + }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production'), + }), + ], + stats: { + colors: true, + children: false, + chunks: false, + modules: false, + }, +} diff --git a/desktop/electron.js b/desktop/electron.js new file mode 100644 index 00000000..684fa9fa --- /dev/null +++ b/desktop/electron.js @@ -0,0 +1,32 @@ +const path = require('path') + +const { app, BrowserWindow } = require('electron') +const server = require('server/dist/server') + +function createWindow() { + // Create the browser window. + const win = new BrowserWindow({ + width: 1920, + height: 1080, + minWidth: 1000, + minHeight: 800, + darkTheme: true, + webPreferences: { + nodeIntegration: true, + }, + }) + + win.loadURL('http://localhost:1176/?settings=1') +} + +// This method will be called when Electron has finished +// initialization and is ready to create browser windows. +// Some APIs can only be used after this event occurs. +app.whenReady().then(createWindow) +app.on('window-all-closed', app.quit) + +app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow() + } +}) diff --git a/desktop/package.json b/desktop/package.json new file mode 100644 index 00000000..ca2d51cc --- /dev/null +++ b/desktop/package.json @@ -0,0 +1,48 @@ +{ + "name": "desktop", + "version": "4.17.0", + "main": "electron.js", + "license": "MIT", + "scripts": { + "build": "yarn build:windows", + "build:macos": "yarn prepare && electron-builder -m", + "build:windows": "yarn prepare && electron-builder -w", + "prepare": "node prepare-package.js" + }, + "dependencies": { + "server": "^1.0.38" + }, + "devDependencies": { + "electron": "16.2.6", + "electron-builder": "22.14.5" + }, + "build": { + "appId": "com.sisyfos-audio-controller.app", + "asar": true, + "directories": { + "output": "dist" + }, + "productName": "Sisyfos Audio Controller" + }, + "description": "Audio mixer build with the logic from a video mixer", + "author": { + "name": "Kasper Olsson Hans (TV2 Denmark)", + "email": "github@olzzon.dk" + }, + "contributors": [ + { + "name": "Balte de Wit", + "email": "balte@superfly.tv", + "url": "https://superfly.tv" + }, + { + "name": "Jan Starzak", + "email": "jan@superfly.tv", + "url": "https://superfly.tv" + }, + { + "name": "Anders Frederik Jørgensen", + "email": "afjo@tv2.dk" + } + ] +} diff --git a/desktop/prepare-package.js b/desktop/prepare-package.js new file mode 100644 index 00000000..97baeb54 --- /dev/null +++ b/desktop/prepare-package.js @@ -0,0 +1,26 @@ +const rootPackage = require('../package.json') +const electronPackage = require('./package.json') +const fs = require('fs') + +const newPackage = { ...electronPackage } +newPackage.version = rootPackage.version +newPackage.description = rootPackage.description +newPackage.license = rootPackage.license +newPackage.author = rootPackage.author +newPackage.contributors = rootPackage.contributors +newPackage.build.productName = rootPackage.name + .split('-') + .map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`) + .join(' ') + +try { + if (JSON.stringify(newPackage) !== JSON.stringify(electronPackage)) { + fs.writeFileSync( + './package.json', + JSON.stringify(newPackage, null, 4), + 'utf-8' + ) + } +} catch (error) { + console.error(error) +} diff --git a/jest.config.js b/jest.config.js deleted file mode 100755 index 037ab60b..00000000 --- a/jest.config.js +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = { - preset: 'ts-jest', - globals: { - 'ts-jest': { - tsConfig: 'tsconfig-test.json', - babelConfig: '.babelrc' - } - }, - testEnvironment: 'node', - testPathIgnorePatterns: [ - "dist", - "integrationTests" - ], - moduleFileExtensions: [ - 'js', - 'ts' - ], - transform: { - '^.+\\.(ts|tsx)$': 'ts-jest', - }, - testMatch: [ - '**/__tests__/**/*.spec.(ts|js)', - ], - coverageThreshold: { - global: { - branches: 0, - functions: 0, - lines: 0, - statements: 0, - }, - }, - coverageDirectory: './coverage/', - collectCoverage: true, -} diff --git a/package.json b/package.json index 55df46e8..bf3db231 100644 --- a/package.json +++ b/package.json @@ -1,100 +1,86 @@ -{ - "name": "sisyfos-audio-controller", - "version": "2.9.5", - "description": "Audio mixer build with the logic from a video mixer", - "license": "MIT", - "private": false, - "author": { - "name": "Kasper Olsson Hans (TV2 Denmark)", - "email": "github@olzzon.dk" - }, - "contributors": [ - { - "name": "Jan Starzak", - "email": "jan@superfly.tv", - "url": "https://superfly.tv" - } - ], - "keywords": [ - "app", - "audio", - "open-source" - ], - "engines": { - "node": ">=8.15.0", - "npm": ">=5.0.0", - "yarn": ">=1.0.0" - }, - "main": "dist/server/index.js", - "scripts": { - "prod": "webpack --mode production --config webpack.config.js && electron --noDevServer .", - "start": "node dist/server/index.js", - "start:dev": "node --inspect dist/server/index.js", - "build-client": "yarn webpack --config webpack.config.js --mode production", - "build-server": "yarn tsc -p server/tsconfig.json", - "build-watch": "yarn tsc -p server/tsconfig.json --watch & webpack --config webpack.config.js --watch --mode development", - "build": "yarn build-server && yarn build-client", - "unit": "jest", - "test": "yarn unit", - "release": "standard-version", - "prepareChangelog": "standard-version --prerelease", - "watch": "jest --watch", - "validate:dependencies": "yarn audit && yarn license-validate", - "license-validate": "node-license-validator -p -d --allow-licenses MIT MIT/X11 BSD BSD-3-Clause BSD-2-Clause ISC Apache Apache-2.0 WTFPL CC-BY-3.0 CC0-1.0 Unlicense --allow-packages cycle" - }, - "dependencies": { - "casparcg-connection": "^4.9.0", - "classnames": "^2.2.6", - "emberplus": "https://github.com/nrkno/tv-automation-emberplus-connection.git", - "express": "^4.17.1", - "express-csp-header": "^2.3.2", - "http": "^0.0.0", - "nouislider-react": "^3.3.7", - "osc": "https://github.com/olzzon/tv2-osc.js-no-serialport.git", - "react": "^16.10.1", - "react-dom": "^16.10.1", - "react-redux": "^7.1.1", - "react-select": "^3.0.6", - "react-slider": "^1.0.2", - "reactjs-popup": "^1.5.0", - "redux": "^4.0.4", - "socket.io": "^2.3.0", - "socket.io-client": "^2.3.0", - "standard-version": "^7.0.1", - "web-midi-api": "^2.0.6", - "webmidi": "^2.5.1", - "winston": "^3.2.1", - "winston-elasticsearch": "^0.8.3" - }, - "devDependencies": { - "@babel/core": "^7.6.2", - "@babel/plugin-proposal-class-properties": "^7.5.5", - "@babel/plugin-proposal-object-rest-spread": "^7.6.2", - "@babel/plugin-syntax-object-rest-spread": "^7.2.0", - "@babel/preset-env": "^7.6.2", - "@babel/preset-react": "^7.0.0", - "@babel/preset-typescript": "^7.6.0", - "@types/hoist-non-react-statics": "^3.3.1", - "@types/jest": "^24.0.23", - "@types/rc-slider": "^8.6.5", - "@types/react-redux": "^7.1.4", - "@types/react-select": "^3.0.4", - "@types/react-test-renderer": "^16.9.1", - "@types/socket.io-client": "^1.4.32", - "babel-jest": "^24.9.0", - "babel-loader": "^8.0.6", - "css-loader": "^3.2.1", - "file-loader": "^4.2.0", - "html-webpack-plugin": "^3.2.0", - "jest": "^24.9.0", - "node-license-validator": "^1.3.0", - "react-test-renderer": "^16.11.0", - "style-loader": "^1.0.1", - "ts-jest": "^24.2.0", - "ts-loader": "^6.2.1", - "ts-node": "^8.6.2", - "typescript": "^3.7.5", - "webpack": "^4.41.0", - "webpack-cli": "^3.3.10" - } -} +{ + "name": "sisyfos-audio-controller", + "version": "4.17.1", + "description": "Audio mixer build with the logic from a video mixer", + "license": "MIT", + "author": { + "name": "Kasper Olsson Hans (TV2 Denmark)", + "email": "github@olzzon.dk" + }, + "contributors": [ + { + "name": "Balte de Wit", + "email": "balte@superfly.tv", + "url": "https://superfly.tv" + }, + { + "name": "Jan Starzak", + "email": "jan@superfly.tv", + "url": "https://superfly.tv" + }, + { + "name": "Anders Frederik Jørgensen", + "email": "afjo@tv2.dk" + } + ], + "keywords": [ + "app", + "audio", + "open-source" + ], + "engines": { + "node": ">=14.17.6", + "yarn": ">=1.0.0" + }, + "private": true, + "workspaces": [ + "client", + "server", + "shared", + "desktop" + ], + "scripts": { + "start": "cross-env NODE_ENV=production node server/dist/server", + "start:dev": "cross-env NODE_ENV=development node --inspect server/dist/server", + "start:local": "cross-env NODE_ENV=local node --inspect server/dist/server", + "build": "yarn build:client && yarn build:server", + "build:client": "yarn --cwd ./client build", + "build:server": "yarn --cwd ./server build", + "build:desktop": "yarn --cwd ./desktop build", + "watch": "concurrently --kill-others \"yarn watch:server\" \"yarn watch:client\"", + "watch:client": "yarn --cwd ./client watch", + "watch:server": "yarn --cwd ./server watch", + "test": "yarn test:client && yarn test:server", + "test:client": "yarn --cwd ./client test", + "test:server": "yarn --cwd ./server test", + "test:watch": "concurrently --kill-others \"yarn --cwd ./client test:watch\" \"yarn --cwd ./server test:watch\"", + "lint": "prettier --write", + "validate": "yarn validate:dependencies && yarn validate:license", + "validate:dependencies": "yarn audit --groups dependencies", + "validate:license": "node-license-validator -p -d --allow-licenses MIT MIT/X11 BSD 0BSD BSD-3-Clause BSD-2-Clause ISC Apache Apache-2.0 WTFPL CC-BY-3.0 CC-BY-4.0 CC0-1.0 GPL Python-2.0 Unlicense --allow-packages cycle", + "clean": "rimraf **/dist **/release", + "reset": "yarn clean && rimraf **/node_modules node_modules" + }, + "simple-git-hooks": { + "pre-commit": "yarn lint-staged" + }, + "lint-staged": { + "*.{js,ts,css,json,md}": [ + "prettier --write" + ] + }, + "dependencies": { + "cross-env": "^7.0.3" + }, + "devDependencies": { + "concurrently": "^8.0.1", + "lint-staged": "^13.2.2", + "node-license-validator": "^1.3.2", + "prettier": "^2.8.8", + "rimraf": "^5.0.0" + }, + "resolutions": { + "xml2js": "^0.5.0", + "socket.io-parser": "^4.2.3" + } +} diff --git a/server/@types/web-midi-api/index.d.ts b/server/@types/web-midi-api/index.d.ts new file mode 100644 index 00000000..8ca084b4 --- /dev/null +++ b/server/@types/web-midi-api/index.d.ts @@ -0,0 +1,3 @@ +declare module 'web-midi-api' { + // To ensure that it can be imported. +} diff --git a/server/MainThreadHandler.ts b/server/MainThreadHandler.ts deleted file mode 100644 index a18c69bb..00000000 --- a/server/MainThreadHandler.ts +++ /dev/null @@ -1,409 +0,0 @@ -import { store, state } from './reducers/store' -import { mixerProtocolList, mixerProtocolPresets, mixerGenericConnection } from './mainClasses' -import { SnapshotHandler } from './utils/SnapshotHandler' -import { socketServer } from './expressHandler' - -import { UPDATE_SETTINGS } from './reducers/settingsActions' -import { - loadSettings, - saveSettings, - getSnapShotList, - getCcgSettingsList, - setCcgDefault -} from './utils/SettingsStorage' -import { - SOCKET_TOGGLE_PGM, - SOCKET_TOGGLE_VO, - SOCKET_TOGGLE_PST, - SOCKET_TOGGLE_PFL, - SOCKET_TOGGLE_MUTE, - SOCKET_SET_FADERLEVEL, - SOCKET_SAVE_SETTINGS, - SOCKET_GET_SNAPSHOT_LIST, - SOCKET_RETURN_SNAPSHOT_LIST, - SOCKET_GET_CCG_LIST, - SOCKET_RETURN_CCG_LIST, - SOCKET_LOAD_SNAPSHOT, - SOCKET_SAVE_SNAPSHOT, - SOCKET_SET_ASSIGNED_FADER, - SOCKET_SET_AUX_LEVEL, - SOCKET_NEXT_MIX, - SOCKET_CLEAR_PST, - SOCKET_SET_THRESHOLD, - SOCKET_SET_RATIO, - SOCKET_SET_LOW, - SOCKET_SET_MID, - SOCKET_SET_HIGH, - SOCKET_RESTART_SERVER, - SOCKET_SET_FADER_MONITOR, - SOCKET_TOGGLE_IGNORE, - SOCKET_SET_FULL_STORE, - SOCKET_SET_STORE_FADER, - SOCKET_SET_STORE_CHANNEL, - SOCKET_SET_LO_MID, - SOCKET_SET_INPUT_OPTION, - SOCKET_SAVE_CCG_FILE, - SOCKET_SET_DELAY_TIME - } from './constants/SOCKET_IO_DISPATCHERS' -import { - TOGGLE_PGM, - TOGGLE_VO, - TOGGLE_PST, - TOGGLE_PFL, - TOGGLE_MUTE, - NEXT_MIX, - CLEAR_PST, - SET_FADER_THRESHOLD, - SET_FADER_RATIO, - SET_FADER_LOW, - SET_FADER_MID, - SET_FADER_HIGH, - SET_FADER_MONITOR, - IGNORE_AUTOMATION, - SET_FADER_LO_MID, - SET_FADER_DELAY_TIME -} from './reducers/faderActions'; -import { SET_FADER_LEVEL } from './reducers/faderActions'; -import { SET_ASSIGNED_FADER, SET_AUX_LEVEL } from './reducers/channelActions'; -import { IChannel } from './reducers/channelsReducer'; -import { logger } from './utils/logger'; -const path = require('path') - -export class MainThreadHandlers { - snapshotHandler: SnapshotHandler - - constructor() { - logger.info('Setting up MainThreadHandlers', {}) - - this.snapshotHandler = new SnapshotHandler() - store.dispatch({ - type:UPDATE_SETTINGS, - settings: loadSettings(state) - }); - } - - updateFullClientStore() { - socketServer.emit(SOCKET_SET_FULL_STORE, state) - } - - updatePartialStore(faderIndex: number) { - state.faders[0].fader[faderIndex] - socketServer.emit( - SOCKET_SET_STORE_FADER, - { - faderIndex: faderIndex, - state: state.faders[0].fader[faderIndex] - } - ) - state.channels[0].channel.forEach((channel: IChannel, index: number) => { - if (channel.assignedFader === faderIndex) { - socketServer.emit( - SOCKET_SET_STORE_CHANNEL, { - channelIndex: index, - state: channel - } - ) - } - }); - } - - socketServerHandlers(socket: any) { - logger.info('SETTING UP SOCKET IO MAIN HANDLERS', {}) - - // get-store get-settings and get-mixerprotocol will be replaces with - // serverside Redux middleware emitter when moved to Socket IO: - socket - .on('get-store', ( - () => { - logger.info('Settings initial store on :' + String(socket.client.id), {}) - this.updateFullClientStore() - }) - ) - .on('get-settings', ( - () => { - socketServer.emit('set-settings', loadSettings(state)) - }) - ) - .on('get-mixerprotocol', ( - () => { - socketServer.emit('set-mixerprotocol', - { - 'mixerProtocol': mixerProtocolPresets[state.settings[0].mixerProtocol], - 'mixerProtocolPresets': mixerProtocolPresets, - 'mixerProtocolList': mixerProtocolList, - - } - ) - }) - ) - .on(SOCKET_GET_SNAPSHOT_LIST, ( - () => { - logger.info('Get snapshot list', {}) - socketServer.emit( - SOCKET_RETURN_SNAPSHOT_LIST, - getSnapShotList() - ) - }) - ) - .on(SOCKET_LOAD_SNAPSHOT, ( - (payload: string) => { - logger.info('Load Snapshot', {}) - this.snapshotHandler.loadSnapshotSettings(path.resolve('storage', payload), false) - this.updateFullClientStore() - }) - ) - .on(SOCKET_SAVE_SNAPSHOT, ( - (payload: string) => { - logger.info('Save Snapshot', {}) - this.snapshotHandler.saveSnapshotSettings(path.resolve('storage', payload)) - - socketServer.emit( - SOCKET_RETURN_SNAPSHOT_LIST, - getSnapShotList() - ) - }) - ) - .on(SOCKET_GET_CCG_LIST, ( - () => { - logger.info('Get snapshot list', {}) - socketServer.emit( - SOCKET_RETURN_CCG_LIST, - getCcgSettingsList() - ) - }) - ) - .on(SOCKET_SAVE_CCG_FILE, ( - (payload: any) => { - logger.info('Set default CCG File :' + String(payload), {}) - setCcgDefault(payload) - this.updateFullClientStore() - }) - ) - .on(SOCKET_SAVE_SETTINGS, ( - (payload: any) => { - logger.info('Save settings :' + String(payload), {}) - saveSettings(payload) - this.updateFullClientStore() - }) - ) - .on(SOCKET_RESTART_SERVER, ( - () => { - process.exit(0) - }) - ) - .on(SOCKET_SET_ASSIGNED_FADER, ( - (payload: any) => { - logger.verbose('Set assigned fader. Channel:' + String(payload.channel) + 'Fader :' +String(payload.faderAssign), {}) - store.dispatch({ - type: SET_ASSIGNED_FADER, - channel: payload.channel, - faderNumber: payload.faderAssign - }) - this.updateFullClientStore() - }) - ) - .on(SOCKET_SET_FADER_MONITOR, ( - (payload: any) => { - store.dispatch({ - type: SET_FADER_MONITOR, - channel: payload.faderIndex, - auxIndex: payload.auxIndex - }); - this.updateFullClientStore() - }) - ) - .on(SOCKET_SET_INPUT_OPTION, ( - (payload: any) => { - mixerGenericConnection.updateChannelSettings(payload.channel, payload.prop, payload.option) - }) - ) - .on(SOCKET_SET_AUX_LEVEL, ( - (payload: any) => { - logger.verbose('Set Auxlevel Channel:' + String(payload.channel), {}) - store.dispatch({ - type: SET_AUX_LEVEL, - channel: payload.channel, - auxIndex: payload.auxIndex, - level: payload.level - }); - mixerGenericConnection.updateAuxLevel(payload.channel, payload.auxIndex) - this.updateFullClientStore() - }) - ) - .on(SOCKET_SET_THRESHOLD, ( - (payload: any) => { - logger.verbose('Set Threshold:' + String(payload.channel), {}) - store.dispatch({ - type: SET_FADER_THRESHOLD, - channel: payload.channel, - level: payload.level - }); - mixerGenericConnection.updateThreshold(payload.channel); - this.updatePartialStore(payload.channel) - }) - ) - .on(SOCKET_SET_RATIO, ( - (payload: any) => { - logger.verbose('Set Ratio:' + String(payload.channel),{}) - store.dispatch({ - type: SET_FADER_RATIO, - channel: payload.channel, - level: payload.level - }); - mixerGenericConnection.updateRatio(payload.channel); - this.updatePartialStore(payload.channel) - }) - ) - .on(SOCKET_SET_DELAY_TIME, ( - (payload: any) => { - logger.verbose('Set Delay:' + String(payload.channel),{}) - store.dispatch({ - type: SET_FADER_DELAY_TIME, - channel: payload.channel, - delayTime: payload.delayTime - }); - mixerGenericConnection.updateDelayTime(payload.channel); - this.updatePartialStore(payload.channel) - }) - ) - .on(SOCKET_SET_LOW, ( - (payload: any) => { - logger.verbose('Set Low:' + String(payload.channel),{}) - store.dispatch({ - type: SET_FADER_LOW, - channel: payload.channel, - level: payload.level - }); - mixerGenericConnection.updateLow(payload.channel); - this.updatePartialStore(payload.channel) - }) - ) - .on(SOCKET_SET_LO_MID, ( - (payload: any) => { - logger.verbose('Set Mid:' + String(payload.level), {}) - store.dispatch({ - type: SET_FADER_LO_MID, - channel: payload.channel, - level: payload.level - }); - mixerGenericConnection.updateLoMid(payload.channel); - this.updatePartialStore(payload.channel) - }) - ) - .on(SOCKET_SET_MID, ( - (payload: any) => { - logger.verbose('Set Mid:' + String(payload.level), {}) - store.dispatch({ - type: SET_FADER_MID, - channel: payload.channel, - level: payload.level - }); - mixerGenericConnection.updateMid(payload.channel); - this.updatePartialStore(payload.channel) - }) - ) - .on(SOCKET_SET_HIGH, ( - (payload: any) => { - logger.verbose('Set High:' + String(payload.channel), {}) - store.dispatch({ - type: SET_FADER_HIGH, - channel: payload.channel, - level: payload.level - }); - mixerGenericConnection.updateHigh(payload.channel); - this.updatePartialStore(payload.channel) - }) - ) - .on(SOCKET_NEXT_MIX, ( - () => { - store.dispatch({ - type: NEXT_MIX - }); - mixerGenericConnection.updateOutLevels() - this.updateFullClientStore() - }) - ) - .on(SOCKET_CLEAR_PST, ( - () => { - store.dispatch({ - type: CLEAR_PST - }); - mixerGenericConnection.updateOutLevels() - this.updateFullClientStore() - }) - ) - .on(SOCKET_TOGGLE_PGM, ( - (faderIndex: any) => { - mixerGenericConnection.checkForAutoResetThreshold(faderIndex) - store.dispatch({ - type: TOGGLE_PGM, - channel: faderIndex - }); - mixerGenericConnection.updateOutLevel(faderIndex) - this.updatePartialStore(faderIndex) - }) - ) - .on(SOCKET_TOGGLE_VO, ( - (faderIndex: any) => { - mixerGenericConnection.checkForAutoResetThreshold(faderIndex) - store.dispatch({ - type: TOGGLE_VO, - channel: faderIndex - }); - mixerGenericConnection.updateOutLevel(faderIndex) - this.updatePartialStore(faderIndex) - }) - ) - .on(SOCKET_TOGGLE_PST, ( - (faderIndex: any) => { - store.dispatch({ - type: TOGGLE_PST, - channel: faderIndex - }); - mixerGenericConnection.updateNextAux(faderIndex); - this.updatePartialStore(faderIndex) - }) - ) - .on(SOCKET_TOGGLE_PFL, ( - (faderIndex: any) => { - store.dispatch({ - type: TOGGLE_PFL, - channel: faderIndex - }); - mixerGenericConnection.updatePflState(faderIndex); - this.updatePartialStore(faderIndex) - }) - ) - .on(SOCKET_TOGGLE_MUTE, ( - (faderIndex: any) => { - store.dispatch({ - type: TOGGLE_MUTE, - channel: faderIndex - }); - mixerGenericConnection.updateMuteState(faderIndex); - this.updatePartialStore(faderIndex) - }) - ) - .on(SOCKET_TOGGLE_IGNORE, ( - (faderIndex: any) => { - store.dispatch({ - type: IGNORE_AUTOMATION, - channel: faderIndex - }); - this.updatePartialStore(faderIndex) - }) - ) - .on(SOCKET_SET_FADERLEVEL, ( - (payload: any) => { - logger.verbose('Set faderlevel Channel : ' + String(payload.faderIndex + 1) + ' Level : ' + String(payload.level)) - store.dispatch({ - type: SET_FADER_LEVEL, - channel: payload.faderIndex, - level: parseFloat(payload.level) - }); - mixerGenericConnection.updateOutLevel(payload.faderIndex) - this.updatePartialStore(payload.faderIndex) - }) - ) - } -} \ No newline at end of file diff --git a/server/__tests__/__mocks__/parsedEmptyStore.json b/server/__tests__/__mocks__/parsedEmptyStore.json index 4c68b0fd..a46cfe14 100644 --- a/server/__tests__/__mocks__/parsedEmptyStore.json +++ b/server/__tests__/__mocks__/parsedEmptyStore.json @@ -1,58 +1,66 @@ -{ - "faders": [ - { - "vuMeters": [], - "fader": [] - } - ], - "channels": [ - { - "channel": [ - { - "channelType": 0, - "channelTypeIndex": 0, - "assignedFader": 0, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - } - ] - } - ], - "settings": [ - { - "showSnaps": false, - "showSettings": false, - "showChanStrip": -1, - "showOptions": false, - "showMonitorOptions": -1, - "showStorage": false, - "mixerProtocol": "sslSystemT", - "localIp": "0.0.0.0", - "localOscPort": 1234, - "deviceIp": "0.0.0.0", - "devicePort": 10024, - "protocolLatency": 220, - "enableRemoteFader": false, - "mixerMidiInputPort": "", - "mixerMidiOutputPort": "", - "remoteFaderMidiInputPort": "", - "remoteFaderMidiOutputPort": "", - "numberOfChannelsInType": [ - 8 - ], - "numberOfFaders": 8, - "numberOfAux": 0, - "nextSendAux": -1, - "numberOfSnaps": 8, - "voLevel": 30, - "autoResetLevel": 5, - "automationMode": true, - "offtubeMode": false, - "fadeTime": 120, - "voFadeTime": 280, - "showPfl": false, - "mixerOnline": false - } - ] -} \ No newline at end of file +{ + "faders": [ + { + "vuMeters": [], + "fader": [] + } + ], + "channels": [ + { + "chMixerConnection": [ + { + "channel": [ + { + "channelType": 0, + "channelTypeIndex": 0, + "assignedFader": 0, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + } + ] + } + ] + } + ], + "settings": [ + { + "showSettings": false, + "showChanStrip": -1, + "showOptions": false, + "showMonitorOptions": -1, + "showStorage": false, + "numberOfMixers": 1, + "mixers": [ + { + "mixerProtocol": "sslSystemT", + "deviceIp": "0.0.0.0", + "devicePort": 10024, + "protocolLatency": 220, + "mixerMidiInputPort": "", + "mixerMidiOutputPort": "", + "numberOfChannelsInType": [8], + "numberOfAux": 0, + "nextSendAux": -1, + "mixerOnline": false, + "localIp": "0.0.0.0", + "localOscPort": 1234 + } + ], + "enableRemoteFader": false, + "remoteFaderMidiInputPort": "", + "remoteFaderMidiOutputPort": "", + "numberOfFaders": 8, + "voLevel": 30, + "autoResetLevel": 5, + "automationMode": true, + "offtubeMode": false, + "fadeTime": 120, + "voFadeTime": 280, + "showPfl": false, + "serverOnline": true, + "currentPage": "undefined", + "customPages": "undefined" + } + ] +} diff --git a/server/__tests__/__mocks__/parsedFullStore.json b/server/__tests__/__mocks__/parsedFullStore.json index 9265ff35..d8d7cb7a 100644 --- a/server/__tests__/__mocks__/parsedFullStore.json +++ b/server/__tests__/__mocks__/parsedFullStore.json @@ -1,964 +1,805 @@ -{ - "faders": [ - { - "vuMeters": [ - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - }, - { - "vuVal": 0 - } - ], - "fader": [ - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 1, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 2, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 3, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 4, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 5, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 6, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 7, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 8, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 9, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 10, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 11, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 12, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 13, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 14, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 15, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 16, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 17, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 18, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 19, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 20, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 21, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 22, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 23, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 24, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - } - ] - } - ], - "channels": [ - { - "channel": [ - { - "channelType": 0, - "channelTypeIndex": 0, - "assignedFader": 0, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 1, - "assignedFader": 1, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 2, - "assignedFader": 2, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 3, - "assignedFader": 3, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 4, - "assignedFader": 4, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 5, - "assignedFader": 5, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 6, - "assignedFader": 6, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 7, - "assignedFader": 7, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 8, - "assignedFader": 8, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 9, - "assignedFader": 9, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 10, - "assignedFader": 10, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 11, - "assignedFader": 11, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 12, - "assignedFader": 12, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 13, - "assignedFader": 13, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 14, - "assignedFader": 14, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 15, - "assignedFader": 15, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 16, - "assignedFader": 16, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 17, - "assignedFader": 17, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 18, - "assignedFader": 18, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 19, - "assignedFader": 19, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 20, - "assignedFader": 20, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 21, - "assignedFader": 21, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 22, - "assignedFader": 22, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - }, - { - "channelType": 0, - "channelTypeIndex": 23, - "assignedFader": 23, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - } - ] - } - ], - "settings": [ - { - "showSnaps": false, - "showSettings": false, - "showChanStrip": -1, - "showOptions": false, - "showMonitorOptions": -1, - "showStorage": false, - "mixerProtocol": "genericMidi", - "localIp": "0.0.0.0", - "localOscPort": 1234, - "deviceIp": "0.0.0.0", - "devicePort": 10024, - "protocolLatency": 20, - "enableRemoteFader": false, - "mixerMidiInputPort": "", - "mixerMidiOutputPort": "", - "remoteFaderMidiInputPort": "", - "remoteFaderMidiOutputPort": "", - "numberOfChannelsInType": [ - 24 - ], - "numberOfFaders": "24", - "numberOfAux": "10", - "nextSendAux": "10", - "numberOfSnaps": 8, - "voLevel": 20, - "autoResetLevel": 10, - "automationMode": true, - "offtubeMode": false, - "fadeTime": 60, - "voFadeTime": 200, - "showPfl": false, - "mixerOnline": false - } - ] -} \ No newline at end of file +{ + "faders": [ + { + "vuMeters": [ + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + }, + { + "reductionVal": 0 + } + ], + "fader": [ + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 1, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 2, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 3, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 4, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 5, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 6, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 7, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 8, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 9, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 10, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 11, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 12, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 13, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 14, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 15, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 16, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 17, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 18, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 19, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 20, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 21, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 22, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 23, + "showChannel": true + }, + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 24, + "showChannel": true + } + ] + } + ], + "channels": [ + { + "chMixerConnection": [ + { + "channel": [ + { + "channelType": 0, + "channelTypeIndex": 0, + "assignedFader": 0, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 1, + "assignedFader": 1, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 2, + "assignedFader": 2, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 3, + "assignedFader": 3, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 4, + "assignedFader": 4, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 5, + "assignedFader": 5, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 6, + "assignedFader": 6, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 7, + "assignedFader": 7, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 8, + "assignedFader": 8, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 9, + "assignedFader": 9, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 10, + "assignedFader": 10, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 11, + "assignedFader": 11, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 12, + "assignedFader": 12, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 13, + "assignedFader": 13, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 14, + "assignedFader": 14, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 15, + "assignedFader": 15, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 16, + "assignedFader": 16, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 17, + "assignedFader": 17, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 18, + "assignedFader": 18, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 19, + "assignedFader": 19, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 20, + "assignedFader": 20, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 21, + "assignedFader": 21, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 22, + "assignedFader": 22, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + }, + { + "channelType": 0, + "channelTypeIndex": 23, + "assignedFader": 23, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + } + ] + } + ] + } + ], + "settings": [ + { + "showSettings": false, + "showChanStrip": -1, + "showOptions": false, + "showMonitorOptions": -1, + "showStorage": false, + "mixerProtocol": "genericMidi", + "numberOfMixers": 1, + "mixers": [ + { + "mixerProtocol": "sslSystemT", + "deviceIp": "0.0.0.0", + "devicePort": 10024, + "protocolLatency": 220, + "mixerMidiInputPort": "", + "mixerMidiOutputPort": "", + "numberOfChannelsInType": [8], + "numberOfAux": 0, + "nextSendAux": -1, + "mixerOnline": false, + "localIp": "0.0.0.0", + "localOscPort": 1234 + } + ], + "enableRemoteFader": false, + "remoteFaderMidiInputPort": "", + "remoteFaderMidiOutputPort": "", + "numberOfFaders": "24", + "voLevel": 20, + "autoResetLevel": 10, + "automationMode": true, + "offtubeMode": false, + "fadeTime": 60, + "voFadeTime": 200, + "showPfl": false, + "serverOnline": true, + "currentPage": "undefined", + "customPages": "undefined" + } + ] +} diff --git a/server/__tests__/__mocks__/parsedSimpleStore.json b/server/__tests__/__mocks__/parsedSimpleStore.json index 8f37ba64..a1cca6d6 100644 --- a/server/__tests__/__mocks__/parsedSimpleStore.json +++ b/server/__tests__/__mocks__/parsedSimpleStore.json @@ -1,90 +1,93 @@ -{ - "faders": [ - { - "vuMeters": [ - { - "vuVal": 0 - } - ], - "fader": [ - { - "faderLevel": 0.75, - "label": "", - "pgmOn": false, - "voOn": false, - "pstOn": false, - "pstVoOn": false, - "pflOn": false, - "muteOn": false, - "low": 0.75, - "mid": 0.75, - "high": 0.75, - "threshold": 0.75, - "ratio": 0.75, - "monitor": 1, - "showChannel": true, - "snapOn": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - } - ] - } - ], - "channels": [ - { - "channel": [ - { - "channelType": 0, - "channelTypeIndex": 0, - "assignedFader": 0, - "fadeActive": false, - "outputLevel": 0, - "auxLevel": [] - } - ] - } - ], - "settings": [ - { - "showSnaps": false, - "showSettings": false, - "showChanStrip": -1, - "showOptions": false, - "showMonitorOptions": -1, - "showStorage": false, - "mixerProtocol": "genericMidi", - "localIp": "0.0.0.0", - "localOscPort": 1234, - "deviceIp": "0.0.0.0", - "devicePort": 10024, - "protocolLatency": 20, - "enableRemoteFader": false, - "mixerMidiInputPort": "", - "mixerMidiOutputPort": "", - "remoteFaderMidiInputPort": "", - "remoteFaderMidiOutputPort": "", - "numberOfChannelsInType": [ - 8 - ], - "numberOfFaders": 8, - "numberOfAux": 0, - "nextSendAux": -1, - "numberOfSnaps": 8, - "voLevel": 20, - "autoResetLevel": 10, - "automationMode": true, - "offtubeMode": false, - "fadeTime": 60, - "voFadeTime": 200, - "showPfl": false, - "mixerOnline": false - } - ] -} \ No newline at end of file +{ + "faders": [ + { + "vuMeters": [ + { + "vuVal": 0, + "reductionVal": 0 + } + ], + "fader": [ + { + "faderLevel": 0.75, + "label": "", + "pgmOn": false, + "voOn": false, + "pstOn": false, + "pstVoOn": false, + "pflOn": false, + "muteOn": false, + "fxParam": [ + { "key": 0, "value": null }, + { "key": 1, "value": null }, + { "key": 2, "value": null }, + { "key": 3, "value": null } + ], + "threshold": 0.75, + "ratio": 0.75, + "monitor": 1, + "showChannel": true + } + ] + } + ], + "channels": [ + { + "chMixerConnection": [ + { + "channel": [ + { + "channelType": 0, + "channelTypeIndex": 0, + "assignedFader": 0, + "fadeActive": false, + "outputLevel": 0, + "auxLevel": [] + } + ] + } + ] + } + ], + "settings": [ + { + "showSettings": false, + "showChanStrip": -1, + "showOptions": false, + "showMonitorOptions": -1, + "showStorage": false, + "mixerProtocol": "genericMidi", + "numberOfMixers": 1, + "mixers": [ + { + "mixerProtocol": "sslSystemT", + "deviceIp": "0.0.0.0", + "devicePort": 10024, + "protocolLatency": 220, + "mixerMidiInputPort": "", + "mixerMidiOutputPort": "", + "numberOfChannelsInType": [8], + "numberOfAux": 0, + "nextSendAux": -1, + "mixerOnline": false, + "localIp": "0.0.0.0", + "localOscPort": 1234 + } + ], + "enableRemoteFader": false, + "remoteFaderMidiInputPort": "", + "remoteFaderMidiOutputPort": "", + "numberOfFaders": 8, + "voLevel": 20, + "autoResetLevel": 10, + "automationMode": true, + "offtubeMode": false, + "fadeTime": 60, + "voFadeTime": 200, + "showPfl": false, + "serverOnline": true, + "currentPage": "undefined", + "customPages": "undefined" + } + ] +} diff --git a/server/__tests__/channelReducer.spec.ts b/server/__tests__/channelReducer.spec.ts index dfccbf4a..3a66b5d7 100644 --- a/server/__tests__/channelReducer.spec.ts +++ b/server/__tests__/channelReducer.spec.ts @@ -1,80 +1,92 @@ -import indexReducer from '../reducers/indexReducer' -import { - FADE_ACTIVE, - SET_ASSIGNED_FADER, - SET_COMPLETE_CH_STATE, - SET_OUTPUT_LEVEL - } from '../reducers/channelActions' -import { IChannel } from '../reducers/channelsReducer' - - let fs = require('fs') -const parsedFullStoreJSON = fs.readFileSync('server/__tests__/__mocks__/parsedFullStore.json') - -describe('Test redux channelReducer actions', () => { - /** - * TEST SET_OUTPUT_LEVEL: - */ - it('should return the new output_level state on channels', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - nextState.channels[0].channel[10].outputLevel = 0.5 - expect(indexReducer(parsedFullStore, { - type: SET_OUTPUT_LEVEL, - channel: 10, - level: '0.5' - })).toEqual(nextState) - }) - - /** - * TEST SET_ASSIGNED_FADER: - */ - it('should return the new assignedFader state on channels', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - nextState.channels[0].channel[10].assignedFader = 2 - expect(indexReducer(parsedFullStore, { - type: SET_ASSIGNED_FADER, - channel: 10, - faderNumber: 2 - })).toEqual(nextState) - }) - - /** - * TEST FADE_ACTIVE: - */ - it('should return the new FADE_ACTIVE state on channels', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - nextState.channels[0].channel[10].fadeActive = true - expect(indexReducer(parsedFullStore, { - type: FADE_ACTIVE, - channel: 10, - active: true - })).toEqual(nextState) - }) - - /** - * TEST SET_COMPLETE_CHANNEL_STATE: - */ - it('should return the new COMPLETE_CHANNEL_STATE on channels', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - let channels: IChannel[] = [] - for (let i=0; i<24; i++) { - channels.push({ - channelType: 0, - channelTypeIndex: i, - assignedFader: i, - auxLevel: [], - fadeActive: false, - outputLevel: 0.75 - }) - nextState.channels[0].channel[i].outputLevel = 0.75 - } - expect(indexReducer(parsedFullStore, { - type: SET_COMPLETE_CH_STATE, - allState: {channel: channels}, - numberOfTypeChannels: [24] - })).toEqual(nextState) - }) -}) +import indexReducer from '../../shared/src/reducers/indexReducer' +import { + storeFadeActive, + storeSetAssignedFader, + storeSetCompleteChState, + storeSetOutputLevel, +} from '../../shared/src/actions/channelActions' +import { + IChannel, + InumberOfChannels, +} from '../../shared/src/reducers/channelsReducer' + +import fs from 'fs' +const parsedFullStoreJSON = fs.readFileSync( + '__tests__/__mocks__/parsedFullStore.json', + 'utf-8' +) + +describe('Test redux channelReducer actions', () => { + /** + * TEST SET_OUTPUT_LEVEL: + */ + + it('should return the new output_level state on channels', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let nextState = JSON.parse(parsedFullStoreJSON) + nextState.channels[0].chMixerConnection[0].channel[10].outputLevel = 0.5 + expect( + indexReducer(parsedFullStore, storeSetOutputLevel(0, 10, 0.5)) + ).toEqual(nextState) + }) + + /** + * TEST SET_ASSIGNED_FADER: + */ + + it('should return the new assignedFader state on channels', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let nextState = JSON.parse(parsedFullStoreJSON) + nextState.channels[0].chMixerConnection[0].channel[10].assignedFader = 2 + expect( + indexReducer(parsedFullStore, storeSetAssignedFader(0, 10, 2)) + ).toEqual(nextState) + }) + + /** + * TEST FADE_ACTIVE: + */ + + it('should return the new FADE_ACTIVE state on channels', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let nextState = JSON.parse(parsedFullStoreJSON) + nextState.channels[0].chMixerConnection[0].channel[10].fadeActive = true + expect( + indexReducer(parsedFullStore, storeFadeActive(0, 10, true)) + ).toEqual(nextState) + }) + + /** + * TEST SET_COMPLETE_CHANNEL_STATE: + */ + + it('should return the new COMPLETE_CHANNEL_STATE on channels', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let nextState = JSON.parse(parsedFullStoreJSON) + let channels: IChannel[] = [] + let numberOfChannels: InumberOfChannels[] = [{ numberOfTypeInCh: [24] }] + + for (let i = 0; i < 24; i++) { + channels.push({ + channelType: 0, + channelTypeIndex: i, + assignedFader: i, + auxLevel: [], + fadeActive: false, + outputLevel: 0.75, + }) + nextState.channels[0].chMixerConnection[0].channel[ + i + ].outputLevel = 0.75 + } + expect( + indexReducer( + parsedFullStore, + storeSetCompleteChState( + { chMixerConnection: [{ channel: channels }] }, + numberOfChannels + ) + ) + ).toEqual(nextState) + }) +}) diff --git a/server/__tests__/faderReducer.spec.ts b/server/__tests__/faderReducer.spec.ts index f058ee20..929918f7 100644 --- a/server/__tests__/faderReducer.spec.ts +++ b/server/__tests__/faderReducer.spec.ts @@ -1,394 +1,324 @@ -import indexReducer from '../reducers/indexReducer' -import { IVuMeters, IFaders } from '../reducers/fadersReducer' -import { - SET_FADER_LEVEL, - SET_PGM, - SET_VO, - SET_PST, - SET_PFL, - SET_MUTE, - SET_CHANNEL_LABEL, - SET_PST_VO, - TOGGLE_SNAP, - TOGGLE_MUTE, - TOGGLE_PFL, - TOGGLE_PGM, - TOGGLE_PST, - TOGGLE_VO, - CLEAR_PST, - FADE_TO_BLACK, - SET_VU_LEVEL, - SHOW_CHANNEL, - NEXT_MIX, - X_MIX, - SET_ALL_VU_LEVELS, - SET_COMPLETE_FADER_STATE -} from '../reducers/faderActions' - -let fs = require('fs') -const parsedSimpleStoreJSON = fs.readFileSync('server/__tests__/__mocks__/parsedSimpleStore.json') -const parsedFullStoreJSON = fs.readFileSync('server/__tests__/__mocks__/parsedFullStore.json') - - -describe('Test redux faderReducers actions', () => { - /** - * TEST ALL SET ACTIONS - */ - it('should return the new fader level state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].faderLevel = 0.5 - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: SET_FADER_LEVEL, - channel: 0, - level: 0.5 - })).toEqual(parsedInitialStore) - }) - - it('should return the new pgmOn state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].pgmOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: SET_PGM, - channel: 0, - pgmOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new voOn state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].voOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: SET_VO, - channel: 0, - voOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new PST state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].pstOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: SET_PST, - channel: 0, - pstOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new PFL state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].pflOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: SET_PFL, - channel: 0, - pflOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new MUTE state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].muteOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: SET_MUTE, - channel: 0, - muteOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new Channel label state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].label = 'NEW LABEL' - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: SET_CHANNEL_LABEL, - channel: 0, - label: 'NEW LABEL' - })).toEqual(parsedInitialStore) - }) - - it('should return the new PST VO state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].pstVoOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: SET_PST_VO, - channel: 0, - pstVoOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new SET_VU_LEVEL state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].vuMeters[0].vuVal = 0.75 - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: SET_VU_LEVEL, - channel: 0, - level: 0.75 - })).toEqual(parsedInitialStore) - }) - - /** - * TEST ALL TOGGLE ACTIONS - */ - - it('should return the new SNAP state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].snapOn[0] = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: TOGGLE_SNAP, - channel: 0, - snapIndex: 0 - })).toEqual(parsedInitialStore) - }) - - it('should return the new TOGGLE pgmOn state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].pgmOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: TOGGLE_PGM, - channel: 0, - pgmOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new TOGGLE VoOn state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].voOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: TOGGLE_VO, - channel: 0, - voOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new TOGGLE_PST state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].pstOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: TOGGLE_PST, - channel: 0, - pstOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new TOGGLE_PFL state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].pflOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: TOGGLE_PFL, - channel: 0, - pflOn: true - })).toEqual(parsedInitialStore) - }) - - it('should return the new TOGGLE_MUTE state on faders', () => { - let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) - parsedInitialStore.faders[0].fader[0].muteOn = true - expect(indexReducer(JSON.parse(parsedSimpleStoreJSON), { - type: TOGGLE_MUTE, - channel: 0, - muteOn: true - })).toEqual(parsedInitialStore) - }) - - - /** - * TEST CLEAR_PST: - */ - it('should SET PST ch 10-14 and return the new CLEAR_PST state on faders', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let newState = JSON.parse(parsedFullStoreJSON) - - for (let i=10; i<14; i++) { - newState.faders[0].fader[i].pstOn = true - expect(indexReducer(parsedFullStore, { - type: SET_PST, - channel: i, - pstOn: true - })).toEqual(newState) - } - - parsedFullStore = JSON.parse(parsedFullStoreJSON) - expect(indexReducer(newState, { - type: CLEAR_PST - })).toEqual(parsedFullStore) - }) - - /** - * TEST FADE_TO_BLACK: - */ - it('should SET VO ch 10-14 and set PGM ch 6-8 and return the new FADE_TO_BLACK state on faders', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let newState = JSON.parse(parsedFullStoreJSON) - - for (let i=10; i<14; i++) { - newState.faders[0].fader[i].voOn = true - expect(indexReducer(parsedFullStore, { - type: SET_VO, - channel: i, - voOn: true - })).toEqual(newState) - } - - for (let i=6; i<8; i++) { - newState.faders[0].fader[i].pgmOn = true - expect(indexReducer(parsedFullStore, { - type: SET_PGM, - channel: i, - pgmOn: true - })).toEqual(newState) - } - - parsedFullStore = JSON.parse(parsedFullStoreJSON) - expect(indexReducer(newState, { - type: FADE_TO_BLACK - })).toEqual(parsedFullStore) - }) - - /** - * TEST NEXT_MIX: - */ - it('should SET PST_VO ch 10-14 and set PST ch 6-8 and return the new NEXT_MIX state on faders', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let newState = JSON.parse(parsedFullStoreJSON) - - for (let i=10; i<14; i++) { - newState.faders[0].fader[i].pstVoOn = true - expect(indexReducer(parsedFullStore, { - type: SET_PST_VO, - channel: i, - pstVoOn: true - })).toEqual(newState) - } - - for (let i=6; i<8; i++) { - newState.faders[0].fader[i].pstOn = true - expect(indexReducer(parsedFullStore, { - type: SET_PST, - channel: i, - pstOn: true - })).toEqual(newState) - } - - // Generate Expected NEXT_MIX: - parsedFullStore = JSON.parse(parsedFullStoreJSON) - for (let i=10; i<14; i++) { - parsedFullStore.faders[0].fader[i].voOn = true - } - for (let i=6; i<8; i++) { - parsedFullStore.faders[0].fader[i].pgmOn = true - } - - expect(indexReducer(newState, { - type: NEXT_MIX - })).toEqual(parsedFullStore) - }) - - /** - * TEST X_MIX: - */ - it('should SET PST_VO ch 10-14 and set PST ch 6-8 and return the new X_MIX state on faders twice', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let newState = JSON.parse(parsedFullStoreJSON) - - for (let i=10; i<14; i++) { - newState.faders[0].fader[i].pstVoOn = true - expect(indexReducer(parsedFullStore, { - type: SET_PST_VO, - channel: i, - pstVoOn: true - })).toEqual(newState) - } - - for (let i=6; i<8; i++) { - newState.faders[0].fader[i].pstOn = true - expect(indexReducer(parsedFullStore, { - type: SET_PST, - channel: i, - pstOn: true - })).toEqual(newState) - } - - // Generate Expected NEXT_MIX: - parsedFullStore = JSON.parse(parsedFullStoreJSON) - for (let i=10; i<14; i++) { - parsedFullStore.faders[0].fader[i].voOn = true - } - for (let i=6; i<8; i++) { - parsedFullStore.faders[0].fader[i].pgmOn = true - } - - // First X_MIX: - expect(indexReducer(newState, { - type: X_MIX - })).toEqual(parsedFullStore) - - // SETUP Expected for second X_MIX: - let finalState = JSON.parse(parsedFullStoreJSON) - for (let i=10; i<14; i++) { - finalState.faders[0].fader[i].pstVoOn = true - } - for (let i=6; i<8; i++) { - finalState.faders[0].fader[i].pstOn = true - } - - // SECOND X_MIX: - expect(indexReducer(newState, { - type: X_MIX - })).toEqual(finalState) - }) - - /** - * TEST SHOW_CHANNEL: - */ - it('should HIDE ch 10 and return the new SHOW_CHANNEL state on faders', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let newState = JSON.parse(parsedFullStoreJSON) - - newState.faders[0].fader[10].showChannel = false - expect(indexReducer(parsedFullStore, { - type: SHOW_CHANNEL, - channel: 10, - showChannel: false - })).toEqual(newState) - }) - - /** - * TEST SET_ALL_VU_LEVELS: - */ - it('should return the new SET_ALL_VU_LEVELS state on faders', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let newState = JSON.parse(parsedFullStoreJSON) - let vuMeters: IVuMeters[] = [] - for (let i=0; i<24; i++) { - vuMeters.push({ - vuVal: 0.75 - }) - newState.faders[0].vuMeters[i].vuVal = 0.75 - } - - expect(indexReducer(parsedFullStore, { - type: SET_ALL_VU_LEVELS, - vuMeters: vuMeters - })).toEqual(newState) - }) - - /** - * TEST SET_COMPLETE_FADER_STATE: - */ - it('should return the new SET_COMPLETE_FADER_STATE state on faders', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let newState = JSON.parse(parsedFullStoreJSON) - let faders: IFaders[] = [] - for (let i=0; i<24; i++) { - faders.push( - parsedFullStore.faders[0].fader[i] - ) - } - - expect(indexReducer(parsedFullStore, { - type: SET_COMPLETE_FADER_STATE, - numberOfTypeChannels: 24, - allState: { - fader: faders - } - })).toEqual(newState) - }) -}) \ No newline at end of file +import indexReducer from '../../shared/src/reducers/indexReducer' +import { IFader, IFaders } from '../../shared/src/reducers/fadersReducer' +import { + storeClearPst, + storeFaderLabel, + storeFaderLevel, + storeFadeToBlack, + storeNextMix, + storeSetCompleteFaderState, + storeSetMute, + storeSetPfl, + storeSetPgm, + storeSetPst, + storeSetPstVo, + storeSetVo, + storeShowChannel, + storeToggleMute, + storeTogglePfl, + storeTogglePgm, + storeTogglePst, + storeToggleVo, + storeXmix, +} from '../../shared/src/actions/faderActions' + +import fs from 'fs' +const parsedSimpleStoreJSON = fs.readFileSync( + '__tests__/__mocks__/parsedSimpleStore.json', + 'utf-8' +) +const parsedFullStoreJSON = fs.readFileSync( + '__tests__/__mocks__/parsedFullStore.json', + 'utf-8' +) + +describe('Test redux faderReducers actions', () => { + /** + * TEST ALL SET ACTIONS + */ + it('should return the new fader level state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].faderLevel = 0.5 + expect( + indexReducer( + JSON.parse(parsedSimpleStoreJSON), + storeFaderLevel(0, 0.5) + ) + ).toEqual(parsedInitialStore) + }) + + it('should return the new pgmOn state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].pgmOn = true + expect( + indexReducer( + JSON.parse(parsedSimpleStoreJSON), + storeSetPgm(0, true) + ) + ).toEqual(parsedInitialStore) + }) + + it('should return the new voOn state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].voOn = true + expect( + indexReducer(JSON.parse(parsedSimpleStoreJSON), storeSetVo(0, true)) + ).toEqual(parsedInitialStore) + }) + + it('should return the new PST state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].pstOn = true + expect( + indexReducer( + JSON.parse(parsedSimpleStoreJSON), + storeSetPst(0, true) + ) + ).toEqual(parsedInitialStore) + }) + + it('should return the new PFL state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].pflOn = true + expect( + indexReducer( + JSON.parse(parsedSimpleStoreJSON), + storeSetPfl(0, true) + ) + ).toEqual(parsedInitialStore) + }) + + it('should return the new MUTE state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].muteOn = true + expect( + indexReducer( + JSON.parse(parsedSimpleStoreJSON), + storeSetMute(0, true) + ) + ).toEqual(parsedInitialStore) + }) + + it('should return the new Channel label state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].label = 'NEW LABEL' + expect( + indexReducer( + JSON.parse(parsedSimpleStoreJSON), + storeFaderLabel(0, 'NEW LABEL') + ) + ).toEqual(parsedInitialStore) + }) + + it('should return the new PST VO state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].pstVoOn = true + expect( + indexReducer( + JSON.parse(parsedSimpleStoreJSON), + storeSetPstVo(0, true) + ) + ).toEqual(parsedInitialStore) + }) + + /** + * TEST ALL TOGGLE ACTIONS + */ + + it('should return the new TOGGLE pgmOn state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].pgmOn = true + expect( + indexReducer(JSON.parse(parsedSimpleStoreJSON), storeTogglePgm(0)) + ).toEqual(parsedInitialStore) + }) + + it('should return the new TOGGLE VoOn state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].voOn = true + expect( + indexReducer(JSON.parse(parsedSimpleStoreJSON), storeToggleVo(0)) + ).toEqual(parsedInitialStore) + }) + + it('should return the new TOGGLE_PST state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].pstOn = true + expect( + indexReducer(JSON.parse(parsedSimpleStoreJSON), storeTogglePst(0)) + ).toEqual(parsedInitialStore) + }) + + it('should return the new TOGGLE_PFL state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].pflOn = true + expect( + indexReducer(JSON.parse(parsedSimpleStoreJSON), storeTogglePfl(0)) + ).toEqual(parsedInitialStore) + }) + + it('should return the new TOGGLE_MUTE state on faders', () => { + let parsedInitialStore = JSON.parse(parsedSimpleStoreJSON) + parsedInitialStore.faders[0].fader[0].muteOn = true + expect( + indexReducer(JSON.parse(parsedSimpleStoreJSON), storeToggleMute(0)) + ).toEqual(parsedInitialStore) + }) + + /** + * TEST CLEAR_PST: + */ + it('should SET PST ch 10-14 and return the new CLEAR_PST state on faders', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let newState = JSON.parse(parsedFullStoreJSON) + + for (let i = 10; i < 14; i++) { + newState.faders[0].fader[i].pstOn = true + expect(indexReducer(parsedFullStore, storeSetPst(i, true))).toEqual( + newState + ) + } + + parsedFullStore = JSON.parse(parsedFullStoreJSON) + expect(indexReducer(newState, storeClearPst())).toEqual(parsedFullStore) + }) + + /** + * TEST FADE_TO_BLACK: + */ + it('should SET VO ch 10-14 and set PGM ch 6-8 and return the new FADE_TO_BLACK state on faders', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let newState = JSON.parse(parsedFullStoreJSON) + + for (let i = 10; i < 14; i++) { + newState.faders[0].fader[i].voOn = true + expect(indexReducer(parsedFullStore, storeSetVo(i, true))).toEqual( + newState + ) + } + + for (let i = 6; i < 8; i++) { + newState.faders[0].fader[i].pgmOn = true + expect(indexReducer(parsedFullStore, storeSetPgm(i, true))).toEqual( + newState + ) + } + + parsedFullStore = JSON.parse(parsedFullStoreJSON) + expect(indexReducer(newState, storeFadeToBlack())).toEqual( + parsedFullStore + ) + }) + + /** + * TEST NEXT_MIX: + */ + it('should SET PST_VO ch 10-14 and set PST ch 6-8 and return the new NEXT_MIX state on faders', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let newState = JSON.parse(parsedFullStoreJSON) + + for (let i = 10; i < 14; i++) { + newState.faders[0].fader[i].pstVoOn = true + expect( + indexReducer(parsedFullStore, storeSetPstVo(i, true)) + ).toEqual(newState) + } + + for (let i = 6; i < 8; i++) { + newState.faders[0].fader[i].pstOn = true + expect(indexReducer(parsedFullStore, storeSetPst(i, true))).toEqual( + newState + ) + } + + // Generate Expected NEXT_MIX: + parsedFullStore = JSON.parse(parsedFullStoreJSON) + for (let i = 10; i < 14; i++) { + parsedFullStore.faders[0].fader[i].voOn = true + } + for (let i = 6; i < 8; i++) { + parsedFullStore.faders[0].fader[i].pgmOn = true + } + + expect(indexReducer(newState, storeNextMix())).toEqual(parsedFullStore) + }) + + /** + * TEST X_MIX: + */ + it('should SET PST_VO ch 10-14 and set PST ch 6-8 and return the new X_MIX state on faders twice', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let newState = JSON.parse(parsedFullStoreJSON) + + for (let i = 10; i < 14; i++) { + newState.faders[0].fader[i].pstVoOn = true + expect( + indexReducer(parsedFullStore, storeSetPstVo(i, true)) + ).toEqual(newState) + } + + for (let i = 6; i < 8; i++) { + newState.faders[0].fader[i].pstOn = true + expect(indexReducer(parsedFullStore, storeSetPst(i, true))).toEqual( + newState + ) + } + + // Generate Expected NEXT_MIX: + parsedFullStore = JSON.parse(parsedFullStoreJSON) + for (let i = 10; i < 14; i++) { + parsedFullStore.faders[0].fader[i].voOn = true + } + for (let i = 6; i < 8; i++) { + parsedFullStore.faders[0].fader[i].pgmOn = true + } + + // First X_MIX: + expect(indexReducer(newState, storeXmix())).toEqual(parsedFullStore) + + // SETUP Expected for second X_MIX: + let finalState = JSON.parse(parsedFullStoreJSON) + for (let i = 10; i < 14; i++) { + finalState.faders[0].fader[i].pstVoOn = true + } + for (let i = 6; i < 8; i++) { + finalState.faders[0].fader[i].pstOn = true + } + + // SECOND X_MIX: + expect(indexReducer(newState, storeXmix())).toEqual(finalState) + }) + + /** + * TEST SHOW_CHANNEL: + */ + it('should HIDE ch 10 and return the new SHOW_CHANNEL state on faders', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let newState = JSON.parse(parsedFullStoreJSON) + + newState.faders[0].fader[10].showChannel = false + expect( + indexReducer(parsedFullStore, storeShowChannel(10, false)) + ).toEqual(newState) + }) + + /** + * TEST SET_COMPLETE_FADER_STATE: + */ + it('should return the new SET_COMPLETE_FADER_STATE state on faders', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let newState = JSON.parse(parsedFullStoreJSON) + let faders: IFader[] = [] + for (let i = 0; i < 24; i++) { + faders.push(parsedFullStore.faders[0].fader[i]) + } + let fullFaderState: IFaders = { fader: faders, vuMeters: [] } + + expect( + indexReducer( + parsedFullStore, + storeSetCompleteFaderState(fullFaderState, 24) + ) + ).toEqual(newState) + }) +}) diff --git a/server/__tests__/indexReducer.spec.ts b/server/__tests__/indexReducer.spec.ts index ba970003..44f0073e 100644 --- a/server/__tests__/indexReducer.spec.ts +++ b/server/__tests__/indexReducer.spec.ts @@ -1,15 +1,20 @@ -import indexReducer from '../reducers/indexReducer' - -let fs = require('fs') -const parsedEmptyStoreJSON = fs.readFileSync('server/__tests__/__mocks__/parsedEmptyStore.json') - -describe('Test initialize store', () => { - let parsedInitialStore = JSON.parse(parsedEmptyStoreJSON) - it('should return the initial state of the whole Store', () => { - // ** Uncomment to update initial settings state: - // let data = indexReducer(undefined, {type: ''}) - // fs.writeFileSync('server/__tests__/__mocks__/parsedEmptyStore-UPDATE.json', JSON.stringify(data)) - - expect(indexReducer(JSON.parse(parsedEmptyStoreJSON), {type: ''})).toEqual(parsedInitialStore) - }) -}) +import indexReducer from '../../shared/src/reducers/indexReducer' + +import fs from 'fs' +const parsedEmptyStoreJSON = fs.readFileSync( + '__tests__/__mocks__/parsedEmptyStore.json', + 'utf-8' +) + +describe('Test initialize store', () => { + let parsedInitialStore = JSON.parse(parsedEmptyStoreJSON) + it('should return the initial state of the whole Store', () => { + // ** Uncomment to update initial settings state: + // let data = indexReducer(undefined, {type: ''}) + // fs.writeFileSync('__tests__/__mocks__/parsedEmptyStore-UPDATE.json', JSON.stringify(data)) + + expect( + indexReducer(JSON.parse(parsedEmptyStoreJSON), { type: '' }) + ).toEqual(parsedInitialStore) + }) +}) diff --git a/server/__tests__/settingsReducer.spec.ts b/server/__tests__/settingsReducer.spec.ts index 7b115946..f7f48597 100644 --- a/server/__tests__/settingsReducer.spec.ts +++ b/server/__tests__/settingsReducer.spec.ts @@ -1,101 +1,109 @@ -import indexReducer from '../reducers/indexReducer' -import { - TOGGLE_SHOW_CHAN_STRIP, - TOGGLE_SHOW_OPTION, - TOGGLE_SHOW_SETTINGS, - TOGGLE_SHOW_SNAPS, - TOGGLE_SHOW_STORAGE, - UPDATE_SETTINGS - } from '../reducers/settingsActions' - - let fs = require('fs') -const parsedFullStoreJSON = fs.readFileSync('server/__tests__/__mocks__/parsedFullStore.json') - -describe('Test redux settingsReducer actions', () => { - /** - * TEST TOGGLE_SHOW_CHAN_STRIP: - */ - it('should return the new showChanStrip state on settings', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - nextState.settings[0].showChanStrip = 3 - expect(indexReducer(parsedFullStore, { - type: TOGGLE_SHOW_CHAN_STRIP, - channel: 3 - })).toEqual(nextState) - - parsedFullStore = JSON.parse(parsedFullStoreJSON) - expect(indexReducer(nextState, { - type: TOGGLE_SHOW_CHAN_STRIP, - channel: -1 - })).toEqual(parsedFullStore) - }) - - /** - * TEST TOGGLE_SHOW_OPTION: - */ - it('should return the new showOptions state on settings', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - nextState.settings[0].showOptions = 3 - expect(indexReducer(parsedFullStore, { - type: TOGGLE_SHOW_OPTION, - channel: 3 - })).toEqual(nextState) - - parsedFullStore = JSON.parse(parsedFullStoreJSON) - expect(indexReducer(nextState, { - type: TOGGLE_SHOW_OPTION, - channel: false - })).toEqual(parsedFullStore) - }) - - /** - * TEST TOGGLE_SHOW_SETTINGS: - */ - it('should return the new showSettings state on settings', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - nextState.settings[0].showSettings = true - expect(indexReducer(parsedFullStore, { - type: TOGGLE_SHOW_SETTINGS - })).toEqual(nextState) - }) - - /** - * TEST TOGGLE_SHOW_SNAPS: - */ - it('should return the new showSnaps state on settings', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - nextState.settings[0].showSnaps = true - expect(indexReducer(parsedFullStore, { - type: TOGGLE_SHOW_SNAPS - })).toEqual(nextState) - }) - - - /** - * TEST TOGGLE_SHOW_STORAGE: - */ - it('should return the new showStorage state on settings', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - nextState.settings[0].showStorage = true - expect(indexReducer(parsedFullStore, { - type: TOGGLE_SHOW_STORAGE - })).toEqual(nextState) - }) - - /** - * TEST UPDATE_SETTINGS: - */ - it('should return the new settings state on settings', () => { - let parsedFullStore = JSON.parse(parsedFullStoreJSON) - let nextState = JSON.parse(parsedFullStoreJSON) - expect(indexReducer(parsedFullStore, { - type: UPDATE_SETTINGS, - settings: parsedFullStore.settings[0] - })).toEqual(nextState) - }) -}) +import indexReducer from '../../shared/src/reducers/indexReducer' +import { + TOGGLE_SHOW_CHAN_STRIP, + TOGGLE_SHOW_OPTION, + TOGGLE_SHOW_SETTINGS, + TOGGLE_SHOW_STORAGE, + UPDATE_SETTINGS, +} from '../../shared/src/actions/settingsActions' + +import fs from 'fs' +const parsedFullStoreJSON = fs.readFileSync( + '__tests__/__mocks__/parsedFullStore.json', + 'utf-8' +) + +describe('Test redux settingsReducer actions', () => { + /** + * TEST TOGGLE_SHOW_CHAN_STRIP: + */ + + it('should return the new showChanStrip state on settings', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let nextState = JSON.parse(parsedFullStoreJSON) + nextState.settings[0].showChanStrip = 3 + expect( + indexReducer(parsedFullStore, { + type: TOGGLE_SHOW_CHAN_STRIP, + channel: 3, + }) + ).toEqual(nextState) + + parsedFullStore = JSON.parse(parsedFullStoreJSON) + expect( + indexReducer(nextState, { + type: TOGGLE_SHOW_CHAN_STRIP, + channel: -1, + }) + ).toEqual(parsedFullStore) + }) + + /** + * TEST TOGGLE_SHOW_OPTION: + */ + + it('should return the new showOptions state on settings', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let nextState = JSON.parse(parsedFullStoreJSON) + nextState.settings[0].showOptions = 3 + expect( + indexReducer(parsedFullStore, { + type: TOGGLE_SHOW_OPTION, + channel: 3, + }) + ).toEqual(nextState) + + parsedFullStore = JSON.parse(parsedFullStoreJSON) + expect( + indexReducer(nextState, { + type: TOGGLE_SHOW_OPTION, + channel: false, + }) + ).toEqual(parsedFullStore) + }) + + /** + * TEST TOGGLE_SHOW_SETTINGS: + */ + + it('should return the new showSettings state on settings', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let nextState = JSON.parse(parsedFullStoreJSON) + nextState.settings[0].showSettings = true + expect( + indexReducer(parsedFullStore, { + type: TOGGLE_SHOW_SETTINGS, + }) + ).toEqual(nextState) + }) + + /** + * TEST TOGGLE_SHOW_STORAGE: + */ + + it('should return the new showStorage state on settings', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let nextState = JSON.parse(parsedFullStoreJSON) + nextState.settings[0].showStorage = true + expect( + indexReducer(parsedFullStore, { + type: TOGGLE_SHOW_STORAGE, + }) + ).toEqual(nextState) + }) + + /** + * TEST UPDATE_SETTINGS: + */ + + it('should return the new settings state on settings', () => { + let parsedFullStore = JSON.parse(parsedFullStoreJSON) + let nextState = JSON.parse(parsedFullStoreJSON) + expect( + indexReducer(parsedFullStore, { + type: UPDATE_SETTINGS, + settings: parsedFullStore.settings[0], + }) + ).toEqual(nextState) + }) +}) diff --git a/server/constants/DEFAULTS.ts b/server/constants/DEFAULTS.ts deleted file mode 100644 index 079f2019..00000000 --- a/server/constants/DEFAULTS.ts +++ /dev/null @@ -1,2 +0,0 @@ -//Mixer Config: -export const NUMBER_OF_SNAPS = 8; diff --git a/server/constants/MixerProtocolInterface.ts b/server/constants/MixerProtocolInterface.ts deleted file mode 100644 index 7c6fd9d6..00000000 --- a/server/constants/MixerProtocolInterface.ts +++ /dev/null @@ -1,144 +0,0 @@ -export interface IMixerProtocolGeneric { - protocol: string, - label: string, - mode: string - fader: { - min: number - max: number - zero: number - step: number - }, - meter: { - min: number, - max: number, - zero: number, - test: number, - }, - channelTypes: Array -} - -export interface IMixerProtocol extends IMixerProtocolGeneric{ - leadingZeros: boolean, - pingCommand: Array, - pingResponseCommand: Array, - pingTime: number, - initializeCommands: Array, -} - -export interface IChannelTypes { - channelTypeName: string, - channelTypeColor: string, - fromMixer: { - CHANNEL_FADER_LEVEL: Array, - CHANNEL_OUT_GAIN: Array, - CHANNEL_VU: Array, - CHANNEL_NAME: Array - PFL: Array - NEXT_SEND: Array - THRESHOLD: Array - RATIO: Array - DELAY_TIME: Array - LOW: Array - LO_MID: Array - MID: Array - HIGH: Array - AUX_LEVEL: Array - CHANNEL_MUTE_ON: Array - CHANNEL_MUTE_OFF: Array - }, - toMixer: { - CHANNEL_FADER_LEVEL: Array, - CHANNEL_OUT_GAIN: Array, - CHANNEL_NAME: Array, - PFL_ON: Array, - PFL_OFF: Array - NEXT_SEND: Array - THRESHOLD: Array - RATIO: Array - DELAY_TIME: Array - LOW: Array - LO_MID: Array - MID: Array - HIGH: Array - AUX_LEVEL: Array - CHANNEL_MUTE_ON: Array - CHANNEL_MUTE_OFF: Array - } -} - -interface IMixerMessageProtocol { - mixerMessage: string, - value: any, - type: string, - min: number, - max: number, - zero: number -} - -export const emptyMixerMessage = (): IMixerMessageProtocol => { - return { - mixerMessage: "none", - value: 0, - type: "", - min: 0, - max: 0, - zero: 0 - } -} - -// CasparCG Specific interfaces: -export interface ICasparCGChannelLayerPair { - channel: number - layer: number -} - -export interface ICasparCGMixerGeometryFile { - label?: string, - channelLabels?: string[], - fromMixer: { - CHANNEL_VU: Array, - } - toMixer: { - PGM_CHANNEL_FADER_LEVEL: Array, - MONITOR_CHANNEL_FADER_LEVEL: Array - } - sourceOptions?: { - sources: Array<(ICasparCGChannelLayerPair & { - producer: string, - file: string - })> - options: { - [key: string]: { // producer property invocation - [key: string]: string // label: property - } - } - } -} - -export interface ICasparCGMixerGeometry extends IMixerProtocolGeneric { - studio: string, - leadingZeros: boolean, - pingTime: number, - fromMixer: { - // CHANNEL_FADER_LEVEL: ChannelLayerPair[], - // CHANNEL_OUT_GAIN: ChannelLayerPair[], - CHANNEL_VU: Array, - }, - toMixer: { - PGM_CHANNEL_FADER_LEVEL: Array, - MONITOR_CHANNEL_FADER_LEVEL: Array, - } - channelLabels?: string[], - sourceOptions?: { - sources: Array<(ICasparCGChannelLayerPair & { - producer: string, - file: string - })> - options: { - [key: string]: { // producer property invocation - [key: string]: string // label: property - } - } - } -} - diff --git a/server/constants/MixerProtocolPresets.ts b/server/constants/MixerProtocolPresets.ts deleted file mode 100644 index 4a94b9b3..00000000 --- a/server/constants/MixerProtocolPresets.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ArdourMaster } from './mixerProtocols/ardourMaster'; -import { ReaperMaster } from './mixerProtocols/reaperMaster'; -import { BehringerXrMaster } from './mixerProtocols/behringerXrMaster'; -import { MidasMaster } from './mixerProtocols/midasMaster'; -import { GenericMidi } from './mixerProtocols/genericMidi'; -import { LawoClient } from './mixerProtocols/EmberLawo'; -import { CasparCGMaster } from './mixerProtocols/casparCGMaster'; -import { DMXIS } from './mixerProtocols/DmxIs'; -import { YamahaQLCL } from './mixerProtocols/yamahaQLCL' -import { SSLSystemT } from './mixerProtocols/SSLsystemT' - -interface IMessageProtocol { - mixerMessage: string, - value: any, - type: string -} -import { StuderVistaMaster } from './mixerProtocols/StuderVistaEmber'; -// Interface: -import { IMixerProtocolGeneric} from './MixerProtocolInterface' - -export const MixerProtocolPresets: { [key: string]: IMixerProtocolGeneric } = Object.assign({ - ardourMaster: ArdourMaster, - reaperMaster: ReaperMaster, - behringerxrmaster: BehringerXrMaster, - midasMaster: MidasMaster, - genericMidi: GenericMidi, - lawoClient: LawoClient, - dmxis: DMXIS, - yamahaQlCl: YamahaQLCL, - sslSystemT: SSLSystemT, - studerVistaMaster: StuderVistaMaster, -}, CasparCGMaster !== undefined ? { - casparCGMaster: CasparCGMaster -} : {}); -/* -*/ - -export const MixerProtocolList = Object.getOwnPropertyNames(MixerProtocolPresets).map((preset) => { - return { - value: preset, - label: MixerProtocolPresets[preset].label - }; -}); diff --git a/server/constants/RemoteFaderPresets.ts b/server/constants/RemoteFaderPresets.ts deleted file mode 100644 index 5c1649ee..00000000 --- a/server/constants/RemoteFaderPresets.ts +++ /dev/null @@ -1,169 +0,0 @@ -//While developing mixer specific settings will be in one file. -//At first release these will be in seperate files -//So it´s easy to add new equipment. - - -export interface IMidiSendMessage { - message: string, - value: any, - type: MidiSendTypes -} - -export enum MidiSendTypes { - disabled, - playNote, - stopNote, - sendControlChange, - sendPitchBend -} - -export interface IMidiReceiveMessage { - message: string, - value: any, - type: MidiReceiveTypes -} -export enum MidiReceiveTypes { - disabled, - noteon, - noteoff, - controlchange, - pitchbend -} - -export interface IRemoteProtocol { - protocol: string, - label: string, - mode: string, - leadingZeros: boolean, - initializeCommands: [ IMidiSendMessage ], - fromRemote: { - CHANNEL_PGM_ON_OFF: IMidiReceiveMessage, - CHANNEL_PST_ON_OFF: IMidiReceiveMessage, - CHANNEL_PFL_ON_OFF: IMidiReceiveMessage, - CHANNEL_FADER_LEVEL: IMidiReceiveMessage, - X_MIX: IMidiReceiveMessage, - FADE_TO_BLACK: IMidiReceiveMessage, - SNAP_RECALL: IMidiReceiveMessage, - }, - toRemote: { - STATE_CHANNEL_PGM: IMidiSendMessage, - STATE_CHANNEL_PST: IMidiSendMessage, - STATE_CHANNEL_PFL: IMidiSendMessage, - STATE_CHANNEL_FADER_LEVEL: Array, - }, - fader: { - min: number, - max: number, - zero: number, - step: number, - }, - meter: { - min: number, - max: number, - zero: number, - test: number, - }, -} - - -export const RemoteFaderPresets: { [key: string]: IRemoteProtocol } = { - hui: { - protocol: 'MIDI', - label: 'Generic HUI Midicontroller', - mode: "client", - leadingZeros: true, - initializeCommands: [ - { - message: "", - value: "", - type: MidiSendTypes.disabled - } - ], - fromRemote: { - CHANNEL_PGM_ON_OFF: { - message: "", - value: "", - type: MidiReceiveTypes.disabled - }, - CHANNEL_PST_ON_OFF: { - message: "", - value: "", - type: MidiReceiveTypes.disabled - }, - CHANNEL_PFL_ON_OFF: { - message: "", - value: "", - type: MidiReceiveTypes.disabled - }, - CHANNEL_FADER_LEVEL: { - message: "0", - value: "", - type: MidiReceiveTypes.controlchange - }, - X_MIX: { - message: "", - value: "", - type: MidiReceiveTypes.disabled - }, - FADE_TO_BLACK: { - message: "", - value: "", - type: MidiReceiveTypes.disabled - }, - SNAP_RECALL: { - message: "", - value: "", - type: MidiReceiveTypes.disabled - }, - }, - toRemote: { - STATE_CHANNEL_PGM: { - message: "", - value: "", - type: MidiSendTypes.disabled - }, - STATE_CHANNEL_PST: { - message: "", - value: "", - type: MidiSendTypes.disabled - }, - STATE_CHANNEL_PFL: { - message: "", - value: "", - type: MidiSendTypes.disabled - }, - STATE_CHANNEL_FADER_LEVEL: [ - { - message: "21", - value: "", - type: MidiSendTypes.sendControlChange - }, - { - message: "01", - value: "", - type: MidiSendTypes.sendControlChange - }, - ], - }, - fader: { - min: 0, - max: 127, - zero: 70, - step: 1, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - }, - } -}; - - -export const RemoteFaderProtocolList = Object.getOwnPropertyNames(RemoteFaderPresets).map((preset) => { - return { - value: preset, - label: RemoteFaderPresets[preset].label - }; -}); diff --git a/server/constants/mixerProtocols/DmxIs.ts b/server/constants/mixerProtocols/DmxIs.ts deleted file mode 100644 index b53a8fa7..00000000 --- a/server/constants/mixerProtocols/DmxIs.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const DMXIS: IMixerProtocol = { - protocol: 'OSC', - label: 'DMXIS Light Controller Protocol', - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. - pingCommand: [emptyMixerMessage()], - pingResponseCommand: [emptyMixerMessage()], - pingTime: 0, //Bypass ping when pingTime is zero - initializeCommands: [emptyMixerMessage()], - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#3f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], //'none' ignores this command - CHANNEL_OUT_GAIN: [{ mixerMessage: '/dmxis/ch/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_VU: [emptyMixerMessage()], - CHANNEL_NAME: [emptyMixerMessage()], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: '/dmxis/ch/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [{ mixerMessage: '/dmxis/ch/name/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - }], - fader: { - min: 0, - max: 1, - zero: 0.75, - step: 0.01, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - }, -} diff --git a/server/constants/mixerProtocols/EmberLawo.ts b/server/constants/mixerProtocols/EmberLawo.ts deleted file mode 100644 index eb6856bf..00000000 --- a/server/constants/mixerProtocols/EmberLawo.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const LawoClient: IMixerProtocol = { - protocol: 'EMBER', - label: 'Lawo Relay VRX4 - client', - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. - pingCommand: [emptyMixerMessage()], - pingResponseCommand: [emptyMixerMessage()], - pingTime: 0, //Bypass ping when pingTime is zero - initializeCommands: [emptyMixerMessage()], - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ - mixerMessage: 'R3LAYVRX4/Ex/GUI/FaderSlot_{channel}/FaderPosition', - value: 0, - type: 'real', - min: 0, - max: 100, - zero: 75 - }], - CHANNEL_VU: [emptyMixerMessage()], - CHANNEL_NAME: [{ - mixerMessage: '', - value: 0, - type: 'real', - min: -200, - max: 20, - zero: 0 - - }], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [{ - mixerMessage: 'R3LAYVRX4/Ex/GUI/FaderSlot_{channel}/FaderPosition', - value: 0, - type: 'real', - min: 0, - max: 100, - zero: 75 - }], - CHANNEL_OUT_GAIN: [{ - mixerMessage: 'R3LAYVRX4/Ex/GUI/FaderSlot_{channel}/Amplification', - value: 0, - type: 'real', - min: -200, - max: 20, - zero: 0 - - }], - CHANNEL_NAME: [{ - mixerMessage: '', - value: 0, - type: 'real', - min: -200, - max: 20, - zero: 0 - - }], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - } - }], - fader: { - min: 0, - max: 200, - zero: 1300, - step: 10, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - } -} - diff --git a/server/constants/mixerProtocols/SSLsystemT.ts b/server/constants/mixerProtocols/SSLsystemT.ts deleted file mode 100644 index a6ffd4a9..00000000 --- a/server/constants/mixerProtocols/SSLsystemT.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const SSLSystemT: IMixerProtocol = { - protocol: 'SSL', - label: 'SSL System T', - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: false, - pingCommand: [emptyMixerMessage()], - pingResponseCommand: [emptyMixerMessage()], - pingTime: 5000, - initializeCommands: [{ mixerMessage: "f1 04 00 00 00 {channel}", value: 0, type: '', min: 0, max: 1, zero: 0.75}], - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], // Handled by SSLMixerconnection - CHANNEL_OUT_GAIN: [emptyMixerMessage()], // Handled by SSLMixerconnection - CHANNEL_VU: [emptyMixerMessage()], // Not implemented in SSL Automation protocol yet - CHANNEL_NAME: [emptyMixerMessage()], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [{ mixerMessage: "f1 04 00 01 00 {channel}", value: 0, type: '', min: 0, max: 1, zero: 0.75}], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: "f1 06 00 80 00 {channel} {level}", value: 0, type: '', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [emptyMixerMessage()], - PFL_ON: [{ mixerMessage: "f1 05 00 80 05 {channel} 01", value: 0, type: '', min: 0, max: 1, zero: 0.75}], - PFL_OFF: [{ mixerMessage: "f1 05 00 80 05 {channel} 00", value: 0, type: '', min: 0, max: 1, zero: 0.75}], - NEXT_SEND: [{ mixerMessage: "f1 06 00 80 00 {channel} {level}", value: 0, type: '', min: 0, max: 1, zero: 0.75}], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [{ mixerMessage: "f1 05 00 80 01 {channel} 00", value: 0, type: '', min: 0, max: 1, zero: 0.75}], - CHANNEL_MUTE_OFF: [{ mixerMessage: "f1 05 00 80 01 {channel} 01", value: 0, type: '', min: 0, max: 1, zero: 0.75}] - }, - }], - fader: { - min: 0, - max: 1, - zero: 0.75, - step: 0.01, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - }, -} diff --git a/server/constants/mixerProtocols/StuderVistaEmber.ts b/server/constants/mixerProtocols/StuderVistaEmber.ts deleted file mode 100644 index 09c333fa..00000000 --- a/server/constants/mixerProtocols/StuderVistaEmber.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const StuderVistaMaster: IMixerProtocol = { - protocol: 'EMBER', - label: 'Studer Vista - master', - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. - pingCommand: [emptyMixerMessage()], - pingResponseCommand: [emptyMixerMessage()], - pingTime: 0, //Bypass ping when pingTime is zero - initializeCommands: [emptyMixerMessage()], - channelTypes: [{ - channelTypeName: 'MONO', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ - mixerMessage: 'System/Mixer/Channels/Inp Mono/Inp Mono #{channel}/Functions/Fader/Value', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - }], - CHANNEL_VU: [emptyMixerMessage()], - CHANNEL_NAME: [{ - mixerMessage: 'System/Mixer/Channels/Inp Mono/Inp Mono #{channel}/Functions/Channel Attribute/User Label', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - }], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ - mixerMessage: 'System/Mixer/Channels/Inp Mono/Inp Mono #{channel}/Functions/Fader/Value', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - - }], - CHANNEL_NAME: [{ - mixerMessage: 'System/Mixer/Channels/Inp Mono/Inp Mono #{channel}/Functions/Channel Attribute/User Label', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - }], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - }, - { - channelTypeName: 'ST', - channelTypeColor: '#3f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ - mixerMessage: 'System/Mixer/Channels/Inp Stereo/Inp Stereo #{channel}/Functions/Fader/Value', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - }], - CHANNEL_VU: [emptyMixerMessage()], - CHANNEL_NAME: [{ - mixerMessage: 'System/Mixer/Channels/Inp Stereo/Inp Stereo #{channel}/Functions/Channel Attribute/User Label', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - }], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ - mixerMessage: 'System/Mixer/Channels/Inp Stereo/Inp Stereo #{channel}/Functions/Fader/Value', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - - }], - CHANNEL_NAME: [{ - mixerMessage: 'System/Mixer/Channels/Inp Stereo/Inp Stereo #{channel}/Functions/Channel Attribute/User Label', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - }], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - }, - { - channelTypeName: 'Inp X', - channelTypeColor: '#2f3f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ - mixerMessage: 'System/Mixer/Channels/Inp 5_1/Inp 5_1 #{channel}/Functions/Fader/Value', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - }], - CHANNEL_VU: [emptyMixerMessage()], - CHANNEL_NAME: [{ - mixerMessage: 'System/Mixer/Channels/Inp 5_1/Inp 5_1 #{channel}/Functions/Channel Attribute/User Label', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - }], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ - mixerMessage: 'System/Mixer/Channels/Inp 5_1/Inp 5_1 #{channel}/Functions/Fader/Value', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - - }], - CHANNEL_NAME: [{ - mixerMessage: 'System/Mixer/Channels/Inp 5_1/Inp 5_1 #{channel}/Functions/Channel Attribute/User Label', - value: 0, - type: 'real', - min: -90, - max: 10, - zero: 0 - }], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - }], - fader: { - min: 0, - max: 100, - zero: 70, - step: 1, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - } -} - diff --git a/server/constants/mixerProtocols/ardourMaster.ts b/server/constants/mixerProtocols/ardourMaster.ts deleted file mode 100644 index a9e7c647..00000000 --- a/server/constants/mixerProtocols/ardourMaster.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const ArdourMaster: IMixerProtocol = { - protocol: 'OSC', - label: 'Ardour DAW - Master Mode', - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: false, - pingCommand: [ - { - mixerMessage: "/strip/list", - value: 0, - type: "i", - min: 0, - max: 1, - zero: 0.75 - } - ], - pingResponseCommand: [ - { - mixerMessage: "/strip/list", - value: 0, - type: "i", - min: 0, - max: 1, - zero: 0.75 - } - ], - pingTime: 9500, - initializeCommands: [ - { - mixerMessage: "/set_surface/feedback", - value: "135", - type: "i", - min: 0, - max: 1, - zero: 0.75 - } - ], - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: '/strip/fader/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_VU: [{ mixerMessage: '/strip/meter/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [{ mixerMessage: '/strip/name/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: '/strip/fader/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [{ mixerMessage: '/strip/name/{channel}', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - } - }], - fader: { - min: 0, - max: 1, - zero: 0.75, - step: 0.01, - }, - meter: { - min: 0, - max: 1, - zero: 0.85, - test: 0.75, - }, -} diff --git a/server/constants/mixerProtocols/behringerXrMaster.ts b/server/constants/mixerProtocols/behringerXrMaster.ts deleted file mode 100644 index 40ca95e0..00000000 --- a/server/constants/mixerProtocols/behringerXrMaster.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const BehringerXrMaster: IMixerProtocol = { - protocol: 'OSC', - label: 'Behringer XR 12,14,16 Mastermode', - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: true, - pingCommand: [ - { - mixerMessage: "/xremote", value: 0, - type: "f", min: 0, max: 1, zero: 0.75 - }, - { - mixerMessage: "/meters", value: "/meters/1", - type: "s", min: 0, max: 1, zero: 0.75 - }, - { - mixerMessage: "/meters", value: "/meters/5", - type: "s", min: 0, max: 1, zero: 0.75 - } - ], - pingResponseCommand: [ - { - mixerMessage: "/xremote", value: 0, - type: "f", min: 0, max: 1, zero: 0.75 - }, - ], - pingTime: 9500, - initializeCommands: [ - { - mixerMessage: "/info", value: 0, type: "f", min: 0, max: 1, zero: 0.75 - } - ], - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], //'none' ignores this command - CHANNEL_OUT_GAIN: [{ mixerMessage: '/ch/{channel}/mix/fader', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_VU: [{ mixerMessage: '/meters/1', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [{ mixerMessage: '/ch/{channel}/config/name', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer : { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: '/ch/{channel}/mix/fader', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [{ mixerMessage: '/ch/{channel}/config/name', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - }], - fader: { - min: 0, - max: 1, - zero: 0.75, - step: 0.01, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - } -} diff --git a/server/constants/mixerProtocols/casparCGMaster.ts b/server/constants/mixerProtocols/casparCGMaster.ts deleted file mode 100644 index 37427848..00000000 --- a/server/constants/mixerProtocols/casparCGMaster.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { ICasparCGMixerGeometry, ICasparCGMixerGeometryFile, emptyMixerMessage } from '../MixerProtocolInterface'; - -// TODO: This is just template data to avoid error if not loading -// default.caspar.ccg from storage folder -// should be simplified when storage is tested on new installations. -let geometry: ICasparCGMixerGeometryFile = { - "label": "Sofie CasparCG Example", - "fromMixer": { - "CHANNEL_VU": [ - ["/channel/1/stage/layer/51/audio/1/pFS", "/channel/1/stage/layer/51/audio/2/pFS"], - ["/channel/1/stage/layer/52/audio/1/pFS", "/channel/1/stage/layer/52/audio/2/pFS"], - ["/channel/1/stage/layer/53/audio/1/pFS", "/channel/1/stage/layer/53/audio/2/pFS"], - ["/channel/1/stage/layer/54/audio/1/pFS", "/channel/1/stage/layer/54/audio/2/pFS"], - ["/channel/1/stage/layer/55/audio/1/pFS", "/channel/1/stage/layer/55/audio/2/pFS"], - ["/channel/1/stage/layer/56/audio/1/pFS", "/channel/1/stage/layer/56/audio/2/pFS"] - ] - }, - "toMixer": { - "MONITOR_CHANNEL_FADER_LEVEL": [ - [ - { "channel": 2, "layer": 51 } - ], - [ - { "channel": 2, "layer": 52 } - ], - [ - { "channel": 2, "layer": 53 } - ], - [ - { "channel": 2, "layer": 54 } - ], - [ - { "channel": 2, "layer": 55 } - ], - [ - { "channel": 2, "layer": 56 } - ] - ], - "PGM_CHANNEL_FADER_LEVEL": [ - [ - { "channel": 1, "layer": 51 }, - { "channel": 3, "layer": 51 } - ], - [ - { "channel": 1, "layer": 52 }, - { "channel": 3, "layer": 52 } - ], - [ - { "channel": 1, "layer": 53 }, - { "channel": 3, "layer": 53 } - ], - [ - { "channel": 1, "layer": 54 }, - { "channel": 3, "layer": 54 } - ], - [ - { "channel": 1, "layer": 55 }, - { "channel": 3, "layer": 55 } - ], - [ - { "channel": 1, "layer": 56 }, - { "channel": 3, "layer": 56 } - ] - ] - }, - "channelLabels": [ - "RM1", - "RM2", - "RM3", - "RM4", - "RM5", - "MP1" - ], - "sourceOptions": { - "sources": [ - { "channel": 2, "layer": 51, "producer": "", "file": "" }, - { "channel": 2, "layer": 52, "producer": "", "file": "" }, - { "channel": 2, "layer": 53, "producer": "", "file": "" }, - { "channel": 2, "layer": 54, "producer": "", "file": "" }, - { "channel": 2, "layer": 55, "producer": "", "file": "" }, - { "channel": 2, "layer": 56, "producer": "", "file": "" } - ], - "options": { - "CHANNEL_LAYOUT": { - "1L-2R": "8ch2", - "1L-1R": "4ch-dleft", - "2L-2R": "4ch-dright" - } - } - } -} - -let CasparCGMasterObject: ICasparCGMixerGeometry | undefined = undefined - -if (geometry) { - CasparCGMasterObject = { - protocol: 'CasparCG', - label: `CasparCG Audio Mixer`, - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - studio: "studio0", - leadingZeros: false, - pingTime: 0, - fromMixer: geometry.fromMixer, - toMixer: geometry.toMixer, - channelLabels: geometry.channelLabels, - sourceOptions: geometry.sourceOptions, - fader: { - min: 0, - max: 1.5, - zero: 1, - step: 0.001, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - }, - //CHANNELTYES ARE NOT IMPLEMENTED. - //THIS IS JUST TO AVOID ERRORS AS - //channelTypes are moved to IMixerProtocolGeneric - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [{ mixerMessage: 'none', value: 0, type: 'f', min: 0, max: 1.5, zero: 1}], - CHANNEL_OUT_GAIN: [{ mixerMessage: 'none', value: 0, type: 'f', min: 0, max: 1.5, zero: 1}], - CHANNEL_VU: [emptyMixerMessage()], - CHANNEL_NAME: [emptyMixerMessage()], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [{ mixerMessage: 'none', value: 0, type: 'f', min: 0, max: 1.5, zero: 1}], - CHANNEL_OUT_GAIN: [{ mixerMessage: 'none', value: 0, type: 'f', min: 0, max: 1.5, zero: 1}], - CHANNEL_NAME: [emptyMixerMessage()], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - }] - } -} - -export const CasparCGMaster = CasparCGMasterObject diff --git a/server/constants/mixerProtocols/genericMidi.ts b/server/constants/mixerProtocols/genericMidi.ts deleted file mode 100644 index 02430f37..00000000 --- a/server/constants/mixerProtocols/genericMidi.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const GenericMidi: IMixerProtocol = { - protocol: 'MIDI', - label: 'Generic Midi', - mode: "client", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: false, - pingCommand: [emptyMixerMessage()], - pingResponseCommand: [emptyMixerMessage()], - pingTime: 0, - initializeCommands: [emptyMixerMessage()], - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [{ mixerMessage: "39", value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], //PgmChange 0 - ignores this command - CHANNEL_OUT_GAIN: [{ mixerMessage: "0", value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], //PgmChange 0 - ignores this command - CHANNEL_VU: [{ mixerMessage: "0", value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], //PgmChange 0 - ignores this command - CHANNEL_NAME: [emptyMixerMessage()], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [{ mixerMessage: "39", value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_OUT_GAIN: [{ mixerMessage: "38", value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [emptyMixerMessage()], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - }], - fader: { - min: 0, - max: 127, - zero: 100, - step: 1, - }, - meter: { - min: 0, - max: 127, - zero: 100, - test: 80, - }, -} diff --git a/server/constants/mixerProtocols/midasMaster.ts b/server/constants/mixerProtocols/midasMaster.ts deleted file mode 100644 index ef262f8e..00000000 --- a/server/constants/mixerProtocols/midasMaster.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const MidasMaster: IMixerProtocol = { - protocol: 'OSC', - label: 'Midas M32 / Behringer X32 Master Mode', - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: true, - pingCommand: [ - { - mixerMessage: "/xremote", - value: 0, - type: "f", - min: 0, - max: 1, zero: 0.75 - }, - { - mixerMessage: "/meters", - value: "/meters/1", - type: "s", - min: 0, - max: 1, zero: 0.75 - } - ], - pingResponseCommand: [ - { - mixerMessage: "/xremote", - value: 0, - type: "f", - min: 0, - max: 1, zero: 0.75 - } - ], - pingTime: 9500, - initializeCommands: [ - { - mixerMessage: '/ch/{channel}/mix/fader', - value: "", - type: "s", - min: 0, - max: 1, - zero: 0.75 - }, - { - mixerMessage: '/ch/{channel}/config/name', - value: "", - type: "s", - min: 0, - max: 1, - zero: 0.75 - }, - { - mixerMessage: '/ch/{channel}/mix/{argument}/level', - value: "", - type: "aux", - min: 0, - max: 1, - zero: 0.75 - }, - { - mixerMessage: '/ch/{channel}/dyn/thr', - value: "", - type: "s", - min: 0, - max: 1, - zero: 0.75 - }, - { - mixerMessage: '/ch/{channel}/dyn/ratio', - value: "", - type: "s", - min: 0, - max: 1, - zero: 0.75 - }, - { - mixerMessage: '/ch/{channel}/delay/time', - value: "", - type: "s", - min: 0, - max: 1, - zero: 0.75 - }, - { - mixerMessage: '/ch/{channel}/eq/1/g', - value: "", - type: "s", - min: 0, - max: 1, - zero: 0.75 - }, - { - mixerMessage: '/ch/{channel}/eq/2/g', - value: "", - type: "s", - min: 0, - max: 1, - zero: 0.75 - }, - { - mixerMessage: '/ch/{channel}/eq/3/g', - value: "", - type: "s", - min: 0, - max: 1, - zero: 0.75 - }, - { - mixerMessage: '/ch/{channel}/eq/4/g', - value: "", - type: "s", - min: 0, - max: 1, - zero: 0.75 - }, - ], - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], //'none' ignores this command - CHANNEL_OUT_GAIN: [{ mixerMessage: '/ch/{channel}/mix/fader', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_VU: [{ mixerMessage: '/meters/1', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [emptyMixerMessage()], //[{ mixerMessage: '/ch/{channel}/config/name', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [{ mixerMessage: '/ch/{channel}/dyn/thr', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - RATIO: [{ mixerMessage: '/ch/{channel}/dyn/ratio', value: 0, type: 'f', min: 0, max: 11, zero: 0}], - DELAY_TIME: [{ mixerMessage: '/ch/{channel}/delay/time', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - LOW: [{ mixerMessage: '/ch/{channel}/eq/1/g', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - LO_MID: [{ mixerMessage: '/ch/{channel}/eq/2/g', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - MID: [{ mixerMessage: '/ch/{channel}/eq/3/g', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - HIGH: [{ mixerMessage: '/ch/{channel}/eq/4/g', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - AUX_LEVEL: [{mixerMessage: '/ch/{channel}/mix/{argument}/level', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - CHANNEL_MUTE_ON: [{ mixerMessage: '/ch/{channel}/mix/on', value: 0, type: 'i', min: 0, max: 1, zero: 0}], - // Only MUTE_ON is used as receiver - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: '/ch/{channel}/mix/fader', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [emptyMixerMessage()], //[{ mixerMessage: '/ch/{channel}/config/name', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [{ mixerMessage: '/ch/{channel}/dyn/thr', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - RATIO: [{ mixerMessage: '/ch/{channel}/dyn/ratio', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - DELAY_TIME: [{ mixerMessage: '/ch/{channel}/delay/time', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - LOW: [{ mixerMessage: '/ch/{channel}/eq/1/g', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - LO_MID: [{ mixerMessage: '/ch/{channel}/eq/2/g', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - MID: [{ mixerMessage: '/ch/{channel}/eq/3/g', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - HIGH: [{ mixerMessage: '/ch/{channel}/eq/4/g', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - AUX_LEVEL: [{mixerMessage: '/ch/{channel}/mix/{argument}/level', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - CHANNEL_MUTE_ON: [{ mixerMessage: '/ch/{channel}/mix/on', value: 0, type: 'f', min: 0, max: 1, zero: 0}], - CHANNEL_MUTE_OFF: [{ mixerMessage: '/ch/{channel}/mix/on', value: 1, type: 'f', min: 0, max: 1, zero: 0}] - }, - }], - fader: { - min: 0, - max: 1, - zero: 0.75, - step: 0.01, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - }, -} diff --git a/server/constants/mixerProtocols/reaperMaster.ts b/server/constants/mixerProtocols/reaperMaster.ts deleted file mode 100644 index d31fff5d..00000000 --- a/server/constants/mixerProtocols/reaperMaster.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const ReaperMaster: IMixerProtocol = { - protocol: 'OSC', - label: 'Reaper DAW Master mode(reaper.fm)', - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. - pingCommand: [emptyMixerMessage()], - pingResponseCommand: [emptyMixerMessage()], - pingTime: 0, //Set to value to get MixerOnline status - initializeCommands: [emptyMixerMessage()], - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: '/track/{channel}/volume', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 }], - CHANNEL_VU: [{ mixerMessage: '/track/{channel}/vu', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 }], - CHANNEL_NAME: [{ mixerMessage: '/track/{channel}/name', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: '/track/{channel}/volume', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 }], - CHANNEL_NAME: [{ mixerMessage: '/track/{channel}/name', value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], - PFL_ON: [{ - mixerMessage: "/track/{channel}/solo", - value: 1, - type: "i", - min: 0, - max: 1, - zero: 0.75 - }], - PFL_OFF: [{ - mixerMessage: "/track/{channel}/solo", - value: 0, - type: "i", - min: 0, - max: 1, - zero: 0.75 - }], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - }, - { - channelTypeName: 'MASTER', - channelTypeColor: '#0f0f3f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: '/master/volume', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 }], - CHANNEL_VU: [ - { mixerMessage: '/master/vu/L', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 }, - { mixerMessage: '/master/vu/R', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 } - ], - CHANNEL_NAME: [emptyMixerMessage()], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: '/master/volume', value: 0, type: 'f', min: 0, max: 1, zero: 0.75 }], - CHANNEL_NAME: [emptyMixerMessage()], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [emptyMixerMessage()], - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - }], - fader: { - min: 0, - max: 1, - zero: 0.75, - step: 0.01, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - }, -} diff --git a/server/constants/mixerProtocols/yamahaQLCL.ts b/server/constants/mixerProtocols/yamahaQLCL.ts deleted file mode 100644 index e10871a5..00000000 --- a/server/constants/mixerProtocols/yamahaQLCL.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface'; - -export const YamahaQLCL: IMixerProtocol = { - protocol: 'QLCL', - label: 'Yamaha QL/CL', - mode: "master", //master (ignores mixers faderlevel, and use faderlevel as gain preset), - //client (use feedback from mixers fader level) - leadingZeros: false, - pingCommand: [emptyMixerMessage()], - pingResponseCommand: [emptyMixerMessage()], - pingTime: 10000, - initializeCommands: [ - { - mixerMessage: 'f0 43 30 3e 19 01 00 37 00 00 {channel} f7', - value: 0, - type: '', - min: 0, - max: 1, - zero: 0.75 - } - ], - channelTypes: [{ - channelTypeName: 'CH', - channelTypeColor: '#2f2f2f', - fromMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], //PgmChange 0 - ignores this command - CHANNEL_OUT_GAIN: [{ mixerMessage: 'f0 43 10 3e 19 01 00 37 00 00 {channel} 00 00 00 {level} f7', value: 0, type: '', min: 0, max: 1, zero: 0.75}], //PgmChange 0 - ignores this command - CHANNEL_VU: [{ mixerMessage: "0", value: 0, type: 'f', min: 0, max: 1, zero: 0.75}], //PgmChange 0 - ignores this command - CHANNEL_NAME: [emptyMixerMessage()], - PFL: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [{ mixerMessage: 'f0 43 10 3e 19 01 00 35 00 00 {channel} 00 00 00 00 00 f7', value: 0, type: '', min: 0, max: 1, zero: 0.75}], - // Only MUTE_ON is used as receiver - CHANNEL_MUTE_OFF: [emptyMixerMessage()] - }, - toMixer: { - CHANNEL_FADER_LEVEL: [emptyMixerMessage()], - CHANNEL_OUT_GAIN: [{ mixerMessage: 'f0 43 10 3e 19 01 00 37 00 00 {channel} 00 00 00 {level} f7', value: 0, type: '', min: 0, max: 1, zero: 0.75}], - CHANNEL_NAME: [emptyMixerMessage()], - PFL_ON: [emptyMixerMessage()], - PFL_OFF: [emptyMixerMessage()], - NEXT_SEND: [emptyMixerMessage()], - THRESHOLD: [emptyMixerMessage()], - RATIO: [emptyMixerMessage()], - DELAY_TIME: [emptyMixerMessage()], - LOW: [emptyMixerMessage()], - LO_MID: [emptyMixerMessage()], - MID: [emptyMixerMessage()], - HIGH: [emptyMixerMessage()], - AUX_LEVEL: [emptyMixerMessage()], - CHANNEL_MUTE_ON: [{ mixerMessage: 'f0 43 10 3e 19 01 00 35 00 00 {channel} 00 00 00 00 00 f7', value: 0, type: '', min: 0, max: 1, zero: 0.75}], - CHANNEL_MUTE_OFF: [{ mixerMessage: 'f0 43 10 3e 19 01 00 35 00 00 {channel} 00 00 00 00 01 f7', value: 0, type: '', min: 0, max: 1, zero: 0.75}] - }, - }], - fader: { - min: 0, - max: 1, - zero: 0.75, - step: 0.01, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - }, -} diff --git a/server/expressHandler.ts b/server/expressHandler.ts deleted file mode 100644 index 61b69bf2..00000000 --- a/server/expressHandler.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { logger } from './utils/logger' - -const express = require('express') -const path = require('path') -const app = express(); -const server = require('http').Server(app); -const socketServer = require('socket.io')(server); - -app.use( '/' , express.static(path.join(__dirname ,'..'))) -server.listen(1176); - -server.on('connection', () => { - app.get('/', (req: any, res: any) => { - res.sendFile(path.resolve('dist/index.html')) - }) - }) - -socketServer.on('connection', ((socket: any) => { - logger.info('Client connected :' + String(socket.client.id), {}) - global.mainThreadHandler.socketServerHandlers(socket) - }) -) - -export const expressInit = () => { - logger.info('Initialising WebServer') -} - -export { socketServer } \ No newline at end of file diff --git a/server/index.ts b/server/index.ts index f55484a4..0bb46a13 100644 --- a/server/index.ts +++ b/server/index.ts @@ -1,15 +1,15 @@ -import { MainThreadHandlers } from './MainThreadHandler' -import { expressInit } from './expressHandler' - -declare global { - namespace NodeJS { - interface Global { - mainThreadHandler: MainThreadHandlers - navigator: any // Workaround for WebMidi - performance: any // Workaround for WebMidi - } - } -} - -global.mainThreadHandler = new MainThreadHandlers() -expressInit() \ No newline at end of file +import { MainThreadHandlers } from './src/MainThreadHandler' +import { expressInit } from './src/expressHandler' + +declare global { + namespace NodeJS { + interface Global { + mainThreadHandler: MainThreadHandlers + navigator: any // Workaround for WebMidi + performance: any // Workaround for WebMidi + } + } +} + +global.mainThreadHandler = new MainThreadHandlers() +expressInit() diff --git a/server/jest.config.js b/server/jest.config.js new file mode 100644 index 00000000..7e6fde04 --- /dev/null +++ b/server/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; + diff --git a/server/mainClasses.ts b/server/mainClasses.ts deleted file mode 100644 index 3f3cb1ff..00000000 --- a/server/mainClasses.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { MixerProtocolPresets, MixerProtocolList } from './constants/MixerProtocolPresets' -import { MixerGenericConnection } from './utils/MixerConnection'; -import { AutomationConnection } from './utils/AutomationConnection'; -import { HuiMidiRemoteConnection } from './utils/HuiMidiRemoteConnection'; - -import { state } from './reducers/store' -let mixerProtocolPresets = MixerProtocolPresets -let mixerProtocolList = MixerProtocolList - -let mixerGenericConnection = new MixerGenericConnection(); -let automationConnection = new AutomationConnection(); -let huiRemoteConnection: HuiMidiRemoteConnection | null = null -if (state.settings[0].enableRemoteFader){ - huiRemoteConnection = new HuiMidiRemoteConnection(); -} - -export { - mixerProtocolList, - mixerProtocolPresets, - mixerGenericConnection, - automationConnection, - huiRemoteConnection -} \ No newline at end of file diff --git a/server/package.json b/server/package.json new file mode 100644 index 00000000..561dafdd --- /dev/null +++ b/server/package.json @@ -0,0 +1,39 @@ +{ + "name": "server", + "version": "0.0.0", + "license": "MIT", + "scripts": { + "build": "tsc", + "watch": "tsc --watch", + "test": "jest", + "test:watch": "jest --watch" + }, + "devDependencies": { + "@types/express": "^4.17.17", + "@types/jest": "^29.5.1", + "@types/node": "^18.16.0", + "@types/webmidi": "^2.0.7", + "jest": "^29.5.0", + "ts-jest": "^29.1.0", + "typescript": "^5.0.4" + }, + "dependencies": { + "@babel/core": "^7.21.8", + "@tv2media/logger": "^2.0.1", + "atem-connection": "^3.2.0", + "casparcg-connection": "^5.1.0", + "emberplus-connection": "^0.1.2", + "express": "^4.18.2", + "node-emberplus": "^3.0.5", + "node-vmix": "^1.6.1", + "osc": "^2.4.4", + "performance-now": "^2.1.0", + "redux": "^4.1.2", + "socket.io": "^4.6.2", + "tslib": "^2.5.0", + "vmix-js-utils": "^4.0.16", + "web-midi-api": "^2.2.5", + "webmidi": "^2.5.1", + "shared": "file:../shared" + } +} diff --git a/server/reducers/channelActions.ts b/server/reducers/channelActions.ts deleted file mode 100644 index 179bd30f..00000000 --- a/server/reducers/channelActions.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const SET_OUTPUT_LEVEL = 'SET_OUTPUT_LEVEL' -export const SET_AUX_LEVEL = 'SET_AUX_LEVEL' -export const SET_COMPLETE_CH_STATE = 'SET_COMPLETE_CH_STATE' -export const SET_SINGLE_CH_STATE = 'SET_SINGLE_CH_STATE' -export const FADE_ACTIVE = 'FADE_ACTIVE' -export const SET_ASSIGNED_FADER = 'SET_ASSIGNED_FADER' -export const SET_PRIVATE = 'SET_PRIVATE' - diff --git a/server/reducers/channelsReducer.ts b/server/reducers/channelsReducer.ts deleted file mode 100644 index 4d9bd5d0..00000000 --- a/server/reducers/channelsReducer.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { - SET_OUTPUT_LEVEL, - SET_ASSIGNED_FADER, - SET_COMPLETE_CH_STATE, - SET_PRIVATE, - FADE_ACTIVE, - SET_AUX_LEVEL, - SET_SINGLE_CH_STATE -} from './channelActions' - -export interface IChannels { - channel: Array -} - -export interface IChannel { - channelType: number, - channelTypeIndex: number, - assignedFader: number, - fadeActive: boolean, - outputLevel: number, - auxLevel: number[], - private?: { - [key: string]: string - } -} - -const defaultChannelsReducerState = (numberOfTypeChannels: Array) => { - let defaultObj: Array = [{ - channel: [] - }]; - - let totalNumberOfChannels = 0; - numberOfTypeChannels.forEach((numberOfChannels, typeIndex) => { - for (let index=0; index < numberOfChannels; index++) { - defaultObj[0].channel[totalNumberOfChannels] = ({ - channelType: typeIndex, - channelTypeIndex: index, - assignedFader: totalNumberOfChannels, - fadeActive: false, - outputLevel: 0.0, - auxLevel: [] - }); - totalNumberOfChannels ++; - } - }) - return defaultObj; -}; - -export const channels = ((state = defaultChannelsReducerState([1]), action: any): Array => { - - let nextState = [{ - channel: [...state[0].channel] - }]; - - switch(action.type) { - case SET_OUTPUT_LEVEL: //channel: level: - nextState[0].channel[action.channel].outputLevel = parseFloat(action.level); - return nextState; - case SET_COMPLETE_CH_STATE: //allState //numberOfChannels - nextState = defaultChannelsReducerState(action.numberOfTypeChannels); - if (action.allState.channel.length == nextState[0].channel.length) { - action.allState.channel.map((channel: any, index: number) => { - if (index < action.numberOfTypeChannels[0]) { - nextState[0].channel[index] = channel; - } - }); - } - return nextState; - case SET_SINGLE_CH_STATE: //channelIndex //state - nextState[0].channel[action.channelIndex] = action.state - return nextState - case FADE_ACTIVE: - nextState[0].channel[action.channel].fadeActive = !!action.active; - return nextState; - case SET_ASSIGNED_FADER: //channel: faderNumber: - nextState[0].channel[action.channel].assignedFader = action.faderNumber - return nextState; - case SET_AUX_LEVEL: //channel: auxIndex: level: - nextState[0].channel[action.channel].auxLevel[action.auxIndex] = parseFloat(action.level); - return nextState; - case SET_PRIVATE: - if (!nextState[0].channel[action.channel].private) { - nextState[0].channel[action.channel].private = {}; - } - nextState[0].channel[action.channel].private![action.tag] = action.value; - return nextState; - default: - return nextState; - } -}); diff --git a/server/reducers/faderActions.ts b/server/reducers/faderActions.ts deleted file mode 100644 index cf688a24..00000000 --- a/server/reducers/faderActions.ts +++ /dev/null @@ -1,33 +0,0 @@ -export const SET_VU_LEVEL = 'SET_VU_LEVEL' -export const SET_COMPLETE_FADER_STATE = 'SET_COMPLETE_FADER_STATE' -export const SET_SINGLE_FADER_STATE = 'SET_SINGLE_FADER_STATE' -export const SET_FADER_LEVEL = 'SET_FADER_LEVEL' -export const SET_ALL_VU_LEVELS = 'SET_ALL_VU_LEVELS' -export const SET_CHANNEL_LABEL = 'SET_CHANNEL_LABEL' -export const SET_FADER_THRESHOLD = 'SET_FADER_THRESHOLD' -export const SET_FADER_RATIO = 'SET_FADER_RATIO' -export const SET_FADER_DELAY_TIME = 'SET_FADER_DELAY_TIME' -export const SET_FADER_LOW = 'SET_FADER_LOW' -export const SET_FADER_LO_MID = 'SET_FADER_LO_MID' -export const SET_FADER_MID = 'SET_FADER_MID' -export const SET_FADER_HIGH = 'SET_FADER_HIGH' -export const SET_FADER_MONITOR = 'SET_FADER_MONITOR' -export const TOGGLE_PGM = 'TOGGLE_PGM' -export const SET_PGM = 'SET_PGM' -export const TOGGLE_VO = 'TOGGLE_VO' -export const SET_VO = 'SET_VO' -export const TOGGLE_PST = 'TOGGLE_PST' -export const SET_PST = 'SET_PST' -export const SET_PST_VO = 'SET_PST_VO' -export const TOGGLE_PFL = 'TOGGLE_PFL' -export const SET_PFL = 'SET_PFL' -export const TOGGLE_MUTE = 'TOGGLE_MUTE' -export const SET_MUTE = 'SET_MUTE' -export const SHOW_CHANNEL = 'SHOW_CHANNEL' -export const IGNORE_AUTOMATION = 'IGNORE_AUTOMATION' -export const TOGGLE_SNAP = 'TOGGLE_SNAP' -export const X_MIX = 'X_MIX' -export const NEXT_MIX = 'NEXT_MIX' -export const FADE_TO_BLACK = 'FADE_TO_BLACK' -export const CLEAR_PST = 'CLEAR_PST' -export const SNAP_RECALL = 'SNAP_RECALL' diff --git a/server/reducers/fadersReducer.ts b/server/reducers/fadersReducer.ts deleted file mode 100644 index 1b11bb0e..00000000 --- a/server/reducers/fadersReducer.ts +++ /dev/null @@ -1,265 +0,0 @@ -import * as DEFAULTS from '../constants/DEFAULTS'; -import { - CLEAR_PST, - FADE_TO_BLACK, - NEXT_MIX, - SET_ALL_VU_LEVELS, - SET_CHANNEL_LABEL, - SET_COMPLETE_FADER_STATE, - SET_FADER_LEVEL, - SET_MUTE, - SET_PFL, - SET_PGM, - SET_PST, - SET_PST_VO, - TOGGLE_SNAP, - SET_VO, - SET_VU_LEVEL, - SHOW_CHANNEL, - IGNORE_AUTOMATION, - SNAP_RECALL, - TOGGLE_MUTE, - TOGGLE_PFL, - TOGGLE_PGM, - TOGGLE_PST, - TOGGLE_VO, - X_MIX, - SET_FADER_THRESHOLD, - SET_FADER_RATIO, - SET_FADER_DELAY_TIME, - SET_FADER_LOW, - SET_FADER_LO_MID, - SET_FADER_MID, - SET_FADER_HIGH, - SET_FADER_MONITOR, - SET_SINGLE_FADER_STATE -} from '../reducers/faderActions' - -export interface IFaders { - fader: Array, - vuMeters: Array, -} - -export interface IFader { - faderLevel: number, - label: string, - pgmOn: boolean, - voOn: boolean, - pstOn: boolean, - pstVoOn: boolean, - pflOn: boolean, - muteOn: boolean, - low: number, - loMid: number - mid: number, - high: number, - threshold: number, - ratio: number, - delayTime: number - monitor: number, - showChannel: boolean, - ignoreAutomation: boolean, - snapOn: Array, -} - -export interface IVuMeters { - vuVal: number -} - -const defaultFadersReducerState = (numberOfFaders: number): IFaders[] => { - let defaultObj: Array = [{ - fader: [], - vuMeters: [], - }]; - - - for (let index=0; index < numberOfFaders; index++) { - defaultObj[0].fader[index] = ({ - faderLevel: 0.75, - label: "", - pgmOn: false, - voOn: false, - pstOn: false, - pstVoOn: false, - pflOn: false, - muteOn: false, - low: 0.75, - loMid: 0.75, - mid: 0.75, - high: 0.75, - threshold: 0.75, - ratio: 0.75, - delayTime: 0, - monitor: (index + 1), // route fader - aux 1:1 as default - showChannel: true, - ignoreAutomation: false, - snapOn: [], - }); - defaultObj[0].vuMeters.push({ - vuVal: 0.0 - }); - for (let y=0; y < DEFAULTS.NUMBER_OF_SNAPS; y++) { - defaultObj[0].fader[index].snapOn.push(false); - } - } - return defaultObj; -}; - -export const faders = ((state = defaultFadersReducerState(0), action: any): Array => { - - let nextState = [{ - vuMeters: [...state[0].vuMeters], - fader: [...state[0].fader], - }]; - - switch(action.type) { - case SET_VU_LEVEL: //channel: level: - if (typeof nextState[0].vuMeters[action.channel] !== 'undefined') { - nextState[0].vuMeters[action.channel].vuVal = parseFloat(action.level); - } - return nextState; - case SET_COMPLETE_FADER_STATE: //allState //numberOfChannels - let emptyState = defaultFadersReducerState(action.numberOfTypeChannels) - if (emptyState[0].vuMeters.length === nextState[0].vuMeters.length) { - emptyState[0].vuMeters = [...state[0].vuMeters] - } - nextState = emptyState - if (action.allState.fader.length == nextState[0].fader.length) { - action.allState.fader.map((channel: any, index: number) => { - nextState[0].fader[index] = channel; - }); - } - return nextState; - case SET_SINGLE_FADER_STATE: //allState //numberOfChannels - nextState[0].fader[action.faderIndex] = action.state - return nextState; - case SET_FADER_LEVEL: //channel: level: - nextState[0].fader[action.channel].faderLevel = parseFloat(action.level); - return nextState; - case SET_FADER_THRESHOLD: //channel: level: - nextState[0].fader[action.channel].threshold = parseFloat(action.level); - return nextState; - case SET_FADER_RATIO: //channel: level: - nextState[0].fader[action.channel].ratio = parseFloat(action.level); - return nextState; - case SET_FADER_DELAY_TIME: //channel: delayTime: - nextState[0].fader[action.channel].delayTime = parseFloat(action.delayTime); - return nextState; - case SET_FADER_LOW: //channel: level: - nextState[0].fader[action.channel].low = parseFloat(action.level); - return nextState; - case SET_FADER_LO_MID: //channel: level: - nextState[0].fader[action.channel].loMid = parseFloat(action.level); - return nextState; - case SET_FADER_MID: //channel: level: - nextState[0].fader[action.channel].mid = parseFloat(action.level); - return nextState; - case SET_FADER_HIGH: //channel: level: - nextState[0].fader[action.channel].high = parseFloat(action.level); - return nextState; - case SET_FADER_MONITOR: //channel: auxIndex: - nextState[0].fader[action.channel].monitor = action.auxIndex; - return nextState; - case SET_ALL_VU_LEVELS: //channel: level: - nextState[0].vuMeters = action.vuMeters; - return nextState; - case SET_CHANNEL_LABEL: //channel: label: - nextState[0].fader[action.channel].label = action.label; - return nextState; - case TOGGLE_PGM: //channel - nextState[0].fader[action.channel].pgmOn = !nextState[0].fader[action.channel].pgmOn; - nextState[0].fader[action.channel].voOn = false; - return nextState; - case SET_PGM: //channel - nextState[0].fader[action.channel].pgmOn = !!action.pgmOn; - nextState[0].fader[action.channel].voOn = false; - return nextState; - case TOGGLE_VO: //channel - nextState[0].fader[action.channel].voOn = !nextState[0].fader[action.channel].voOn; - nextState[0].fader[action.channel].pgmOn = false; - return nextState; - case SET_VO: //channel - nextState[0].fader[action.channel].voOn = !!action.voOn; - nextState[0].fader[action.channel].pgmOn = false; - return nextState; - case TOGGLE_PST: //channel - if (nextState[0].fader[action.channel].pstOn) { - nextState[0].fader[action.channel].pstOn = false; - // Disable toggle to pstVoOn, to enable change pstVoOn: true here: - nextState[0].fader[action.channel].pstVoOn = false; - } else if (nextState[0].fader[action.channel].pstVoOn) { - nextState[0].fader[action.channel].pstOn = false; - nextState[0].fader[action.channel].pstVoOn = false; - } else { - nextState[0].fader[action.channel].pstOn = true; - nextState[0].fader[action.channel].pstVoOn = false; - } - return nextState; - case SET_PST: //channel - nextState[0].fader[action.channel].pstOn = !!action.pstOn; - nextState[0].fader[action.channel].pstVoOn = false; - return nextState; - case SET_PST_VO: //channel - nextState[0].fader[action.channel].pstVoOn = !!action.pstVoOn; - nextState[0].fader[action.channel].pstOn = false; - return nextState; - case TOGGLE_PFL: //channel - nextState[0].fader[action.channel].pflOn = !nextState[0].fader[action.channel].pflOn; - return nextState; - case SET_PFL: //channel - nextState[0].fader[action.channel].pflOn = !!action.pflOn; - return nextState; - case TOGGLE_MUTE: //channel - nextState[0].fader[action.channel].muteOn = !nextState[0].fader[action.channel].muteOn; - return nextState; - case SET_MUTE: //channel - nextState[0].fader[action.channel].muteOn = !!action.muteOn; - return nextState; - case SHOW_CHANNEL: //channel // showChannel - nextState[0].fader[action.channel].showChannel = !!action.showChannel; - return nextState; - case IGNORE_AUTOMATION: //channel // ignoreAutomation - nextState[0].fader[action.channel].ignoreAutomation = !nextState[0].fader[action.channel].ignoreAutomation - return nextState; - case TOGGLE_SNAP: //channel //snapIndex - nextState[0].fader[action.channel].snapOn[action.snapIndex] = !nextState[0].fader[action.channel].snapOn[action.snapIndex]; - return nextState; - case X_MIX: //none - nextState[0].fader.map((item, index) => { - let nextPgmOn = state[0].fader[index].pstOn; - let nextVoOn = state[0].fader[index].pstVoOn; - nextState[0].fader[index].pstOn = state[0].fader[index].pgmOn; - nextState[0].fader[index].pstVoOn = state[0].fader[index].voOn; - nextState[0].fader[index].pgmOn = nextPgmOn; - nextState[0].fader[index].voOn = nextVoOn; - }); - return nextState; - case NEXT_MIX: //none - nextState[0].fader.map((item, index) => { - nextState[0].fader[index].pgmOn = state[0].fader[index].pstOn; - nextState[0].fader[index].voOn = state[0].fader[index].pstVoOn; - nextState[0].fader[index].pstOn = false; - nextState[0].fader[index].pstVoOn = false; - }); - return nextState; - case FADE_TO_BLACK: //none - nextState[0].fader.map((item, index) => { - nextState[0].fader[index].pgmOn = false; - nextState[0].fader[index].voOn = false; - }); - return nextState; - case CLEAR_PST: //none - nextState[0].fader.map((item, index) => { - nextState[0].fader[index].pstOn = false; - nextState[0].fader[index].pstVoOn = false; - }); - return nextState; - case SNAP_RECALL: //snapIndex - nextState[0].fader.map((item, index) => { - nextState[0].fader[index].pstOn = !!state[0].fader[index].snapOn[action.snapIndex]; - }); - return nextState; - default: - return nextState; - } -}); diff --git a/server/reducers/indexReducer.ts b/server/reducers/indexReducer.ts deleted file mode 100644 index 483e80b1..00000000 --- a/server/reducers/indexReducer.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { combineReducers } from 'redux'; -import { IChannels, channels} from './channelsReducer'; -import { ISettings, settings } from './settingsReducer'; -import {  IFaders, faders, } from './fadersReducer'; - -export interface IStore { - settings: Array, - channels: Array, - faders: Array -}; - -const indexReducer = combineReducers({ - faders, - channels, - settings -}); - -export default indexReducer; diff --git a/server/reducers/settingsActions.ts b/server/reducers/settingsActions.ts deleted file mode 100644 index a8c77862..00000000 --- a/server/reducers/settingsActions.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const TOGGLE_SHOW_SETTINGS = 'TOGGLE_SHOW_SETTINGS' -export const TOGGLE_SHOW_CHAN_STRIP = 'TOGGLE_SHOW_CHAN_STRIP' -export const TOGGLE_SHOW_OPTION = 'TOGGLE_SHOW_OPTION' -export const TOGGLE_SHOW_MONITOR_OPTIONS = 'TOGGLE_SHOW_MONITOR_OPTIONS' -export const TOGGLE_SHOW_STORAGE = 'TOGGLE_SHOW_STORAGE' -export const TOGGLE_SHOW_SNAPS = 'TOGGLE_SHOW_SNAPS' -export const UPDATE_SETTINGS = 'UPDATE_SETTINGS' -export const SET_MIXER_ONLINE = 'SET_MIXER_ONLINE' diff --git a/server/reducers/settingsReducer.ts b/server/reducers/settingsReducer.ts deleted file mode 100644 index c3a672a3..00000000 --- a/server/reducers/settingsReducer.ts +++ /dev/null @@ -1,133 +0,0 @@ -import * as DEFAULTS from '../constants/DEFAULTS'; -import { MixerProtocolPresets } from '../constants/MixerProtocolPresets'; -import { - TOGGLE_SHOW_CHAN_STRIP, - TOGGLE_SHOW_OPTION, - TOGGLE_SHOW_SETTINGS, - TOGGLE_SHOW_SNAPS, - TOGGLE_SHOW_STORAGE, - UPDATE_SETTINGS, - SET_MIXER_ONLINE, - TOGGLE_SHOW_MONITOR_OPTIONS -} from '../reducers/settingsActions' - -export interface ISettings { - showSnaps: boolean, - showSettings: boolean, - showChanStrip: number, - showOptions: number | false, - showMonitorOptions: number, - showStorage: boolean, - mixerProtocol: string, - localIp: string, - localOscPort: number, - deviceIp: string, - devicePort: number, - protocolLatency: number, // If a protocol has latency and feedback, the amount of time before enabling receiving data from channel again - enableRemoteFader: boolean, - mixerMidiInputPort: string, - mixerMidiOutputPort: string, - remoteFaderMidiInputPort: string, - remoteFaderMidiOutputPort: string, - numberOfChannelsInType: Array, - numberOfFaders: number, - numberOfAux: number, - nextSendAux: number, - numberOfSnaps: number, - fadeTime: number, // Default fade time for PGM ON - OFF - voFadeTime: number, // Default fade time for VO ON - OFF - voLevel: number, // Relative level of PGM in % - autoResetLevel: number, // Autoreset before pgm on, if level is lower than in % - automationMode: boolean, - offtubeMode: boolean, - showPfl: boolean, - mixerOnline: boolean -} - - -const defaultSettingsReducerState: Array = [ - { - showSnaps: false, - showSettings: false, - showChanStrip: -1, - showOptions: false, - showMonitorOptions: -1, - showStorage: false, - mixerProtocol: "sslSystemT", - localIp: "0.0.0.0", - localOscPort: 1234, - deviceIp: "0.0.0.0", - devicePort: 10024, - protocolLatency: 220, - enableRemoteFader: false, - mixerMidiInputPort: "", - mixerMidiOutputPort: "", - remoteFaderMidiInputPort: "", - remoteFaderMidiOutputPort: "", - numberOfChannelsInType: [8], - numberOfFaders: 8, - numberOfAux: 0, - nextSendAux: -1, - numberOfSnaps: DEFAULTS.NUMBER_OF_SNAPS, - voLevel: 30, - autoResetLevel: 5, - automationMode: true, - offtubeMode: false, - fadeTime: 120, - voFadeTime: 280, - showPfl: false, - mixerOnline: false - }, -]; - -export const settings = (state = defaultSettingsReducerState, action: any): Array => { - let nextState = [Object.assign({}, state[0])]; - - switch (action.type) { - case TOGGLE_SHOW_SETTINGS: - nextState[0].showSettings = !nextState[0].showSettings; - return nextState; - case TOGGLE_SHOW_CHAN_STRIP: - if (nextState[0].showChanStrip !== action.channel) { - nextState[0].showChanStrip = action.channel; - } - else { - nextState[0].showChanStrip = -1; - } - return nextState; - case TOGGLE_SHOW_MONITOR_OPTIONS: - if (nextState[0].showMonitorOptions !== action.channel) { - nextState[0].showMonitorOptions = action.channel; - } - else { - nextState[0].showMonitorOptions = -1; - } - return nextState; - case TOGGLE_SHOW_OPTION: - nextState[0].showOptions = typeof nextState[0].showOptions === 'number' ? false : action.channel; - return nextState; - case TOGGLE_SHOW_STORAGE: - nextState[0].showStorage = !nextState[0].showStorage; - return nextState; - case TOGGLE_SHOW_SNAPS: - nextState[0].showSnaps = !nextState[0].showSnaps; - return nextState; - case SET_MIXER_ONLINE: - nextState[0].mixerOnline = action.mixerOnline; - return nextState; - case UPDATE_SETTINGS: - nextState[0] = action.settings; - nextState[0].showSettings = state[0].showSettings; - nextState[0].showOptions = state[0].showOptions; - nextState[0].showMonitorOptions = state[0].showMonitorOptions; - nextState[0].showStorage = state[0].showStorage; - nextState[0].showChanStrip = state[0].showChanStrip; - if (typeof MixerProtocolPresets[nextState[0].mixerProtocol] === 'undefined') - { - nextState[0].mixerProtocol = 'genericMidi'; - } - return nextState; - default: - return nextState; - } -}; diff --git a/server/reducers/store.ts b/server/reducers/store.ts deleted file mode 100644 index c52461ad..00000000 --- a/server/reducers/store.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { createStore } from 'redux' -import indexReducer from './indexReducer'; -import { UPDATE_SETTINGS } from './settingsActions' -import { loadSettings } from '../utils/SettingsStorage' - -let storeRedux = createStore( - indexReducer -) - -storeRedux.dispatch({ - type:UPDATE_SETTINGS, - settings: loadSettings(storeRedux.getState()) -}) - -//Subscribe to redux store: -let state = storeRedux.getState(); -const unsubscribe = storeRedux.subscribe(() => { - state = storeRedux.getState(); -}); - -export { storeRedux as store } -export { state } \ No newline at end of file diff --git a/server/src/MainThreadHandler.ts b/server/src/MainThreadHandler.ts new file mode 100644 index 00000000..0673ecc3 --- /dev/null +++ b/server/src/MainThreadHandler.ts @@ -0,0 +1,421 @@ +import { store, state } from './reducers/store' +import { + mixerProtocolList, + mixerProtocolPresets, + mixerGenericConnection, + remoteConnections, +} from './mainClasses' +import { SnapshotHandler } from './utils/SnapshotHandler' +import { socketServer } from './expressHandler' + +import { storeUpdateSettings } from '../../shared/src/actions/settingsActions' +import * as IO from '../../shared/src/constants/SOCKET_IO_DISPATCHERS' +import * as FADER_ACTIONS from '../../shared/src/actions/faderActions' + +import { + loadSettings, + saveSettings, + getSnapShotList, + getCcgSettingsList, + setCcgDefault, + getMixerPresetList, + getCustomPages, + saveCustomPages, + STORAGE_FOLDER, +} from './utils/SettingsStorage' + +import { + storeFlushChLabels, + storeSetAssignedFader, + storeSetAuxLevel, +} from '../../shared/src/actions/channelActions' +import { logger } from './utils/logger' +import { ICustomPages } from '../../shared/src/reducers/settingsReducer' +import { fxParamsList } from '../../shared/src/constants/MixerProtocolInterface' +import path from 'path' +import { IChannel } from '../../shared/src/reducers/channelsReducer' + +export class MainThreadHandlers { + snapshotHandler: SnapshotHandler + + constructor() { + logger.info('Setting up MainThreadHandlers') + + this.snapshotHandler = new SnapshotHandler() + store.dispatch(storeUpdateSettings(loadSettings(state))) + } + + updateFullClientStore() { + this.recalcAssignedChannels() + socketServer.emit(IO.SOCKET_SET_FULL_STORE, state) + } + + updatePartialStore(faderIndex: number) { + socketServer.emit(IO.SOCKET_SET_STORE_FADER, { + faderIndex: faderIndex, + state: state.faders[0].fader[faderIndex], + }) + state.channels[0].chMixerConnection.forEach((chMixerConnection) => { + chMixerConnection.channel.forEach( + (channel: IChannel, index: number) => { + if (channel.assignedFader === faderIndex) { + socketServer.emit(IO.SOCKET_SET_STORE_CHANNEL, { + channelIndex: index, + state: channel, + }) + } + } + ) + }) + } + + updateMixerOnline(mixerIndex: number, onLineState?: boolean) { + socketServer.emit(IO.SOCKET_SET_MIXER_ONLINE, { + mixerIndex, + mixerOnline: + onLineState ?? state.settings[0].mixers[mixerIndex].mixerOnline, + }) + } + + // Assigned channel to faders are right now based on Channel.assignedFader + // Plan is to change it so fader.assignedChannel will be the master (a lot of change in code is needed) + recalcAssignedChannels() { + store.dispatch(FADER_ACTIONS.removeAllAssignedChannels()) + state.channels[0].chMixerConnection.forEach((mixer, mixerIndex) => { + mixer.channel.forEach((channel: IChannel, channelIndex) => { + if ( + channel.assignedFader >= 0 && + state.faders[0].fader[channel.assignedFader] + ) { + store.dispatch( + FADER_ACTIONS.storeSetAssignedChannel( + channel.assignedFader, + mixerIndex, + channelIndex, + true + ) + ) + } + }) + }) + } + + socketServerHandlers(socket: any) { + logger.info('Setting up socket IO main handlers.') + + // get-store get-settings and get-mixerprotocol will be replaces with + // serverside Redux middleware emitter when moved to Socket IO: + socket + .on('get-store', () => { + logger.info(`Setting initial store on: ${socket.client.id}`) + this.updateFullClientStore() + }) + .on('get-settings', () => { + socketServer.emit('set-settings', state.settings[0]) + }) + .on('get-mixerprotocol', () => { + socketServer.emit('set-mixerprotocol', { + mixerProtocol: + mixerProtocolPresets[ + state.settings[0].mixers[0].mixerProtocol + ], + mixerProtocolPresets: mixerProtocolPresets, + mixerProtocolList: mixerProtocolList, + }) + }) + .on(IO.SOCKET_GET_SNAPSHOT_LIST, () => { + logger.info('Get snapshot list') + socketServer.emit( + IO.SOCKET_RETURN_SNAPSHOT_LIST, + getSnapShotList() + ) + }) + .on(IO.SOCKET_LOAD_SNAPSHOT, (payload: string) => { + logger.info('Load Snapshot') + this.snapshotHandler.loadSnapshotSettings( + path.join(STORAGE_FOLDER, payload), + true + ) + this.updateFullClientStore() + }) + .on(IO.SOCKET_SAVE_SNAPSHOT, (payload: string) => { + logger.info('Save Snapshot') + this.snapshotHandler.saveSnapshotSettings( + path.join(STORAGE_FOLDER, payload) + ) + + socketServer.emit( + IO.SOCKET_RETURN_SNAPSHOT_LIST, + getSnapShotList() + ) + }) + .on(IO.SOCKET_GET_CCG_LIST, () => { + logger.info('Get CCG settings list') + socketServer.emit( + IO.SOCKET_RETURN_CCG_LIST, + getCcgSettingsList() + ) + }) + .on(IO.SOCKET_GET_MIXER_PRESET_LIST, () => { + logger.info('Get Preset list') + socketServer.emit( + IO.SOCKET_RETURN_MIXER_PRESET_LIST, + getMixerPresetList( + mixerGenericConnection.getPresetFileExtention() + ) + ) + }) + .on(IO.SOCKET_SAVE_CCG_FILE, (payload: any) => { + logger.info(`Set default CCG File: ${payload}`) + setCcgDefault(payload) + this.updateFullClientStore() + }) + .on(IO.SOCKET_LOAD_MIXER_PRESET, (payload: any) => { + logger.info(`Set Mixer Preset: ${payload}`) + mixerGenericConnection.loadMixerPreset(payload) + this.updateFullClientStore() + }) + .on(IO.SOCKET_GET_PAGES_LIST, () => { + logger.info('Get custom pages list') + let customPages: ICustomPages[] = getCustomPages() + if ( + customPages.length === state.settings[0].numberOfCustomPages + ) { + socketServer.emit(IO.SOCKET_RETURN_PAGES_LIST, customPages) + } else { + for ( + let i = 0; + i < state.settings[0].numberOfCustomPages; + i++ + ) { + if (!customPages[i]) { + customPages.push({ + id: 'custom' + String(i), + label: 'Custom ' + String(i), + faders: [], + }) + } + } + socketServer.emit( + IO.SOCKET_RETURN_PAGES_LIST, + customPages.slice( + 0, + state.settings[0].numberOfCustomPages + ) + ) + } + }) + .on(IO.SOCKET_SET_PAGES_LIST, (payload: any) => { + saveCustomPages(payload) + logger.info(`Save custom pages list: ${payload}`) + }) + .on(IO.SOCKET_SAVE_SETTINGS, (payload: any) => { + logger.data(payload).info('Save settings:') + saveSettings(payload) + this.updateFullClientStore() + /** Delay restart to ensure the async saveSettings is done before restarting*/ + setTimeout(() => { + process.exit(0) + }, 1000) + }) + .on(IO.SOCKET_RESTART_SERVER, () => { + process.exit(0) + }) + .on(IO.SOCKET_SET_ASSIGNED_FADER, (payload: any) => { + logger.trace( + `Set assigned fader.\n Mixer: ${ + payload.mixerIndex + 1 + }\n Channel: ${payload.channel}\n Fader: ${ + payload.faderAssign + }` + ) + store.dispatch( + storeSetAssignedFader( + payload.mixerIndex, + payload.channel, + payload.faderAssign + ) + ) + + this.updateFullClientStore() + }) + .on(IO.SOCKET_SET_FADER_MONITOR, (payload: any) => { + store.dispatch( + FADER_ACTIONS.storeFaderMonitor( + payload.faderIndex, + payload.auxIndex + ) + ) + this.updateFullClientStore() + }) + .on(IO.SOCKET_SHOW_IN_MINI_MONITOR, (payload: any) => { + store.dispatch( + FADER_ACTIONS.storeShowInMiniMonitor( + payload.faderIndex, + payload.showInMiniMonitor + ) + ) + this.updateFullClientStore() + }) + .on(IO.SOCKET_SET_INPUT_OPTION, (payload: any) => { + mixerGenericConnection.updateChannelSettings( + payload.channel, + payload.prop, + payload.option + ) + }) + .on(IO.SOCKET_SET_AUX_LEVEL, (payload: any) => { + logger.trace( + `Set Auxlevel Channel: ${payload.channel} Auxindex : ${payload.auxIndex} level : ${payload.level}` + ) + store.dispatch( + storeSetAuxLevel( + 0, + payload.channel, + payload.auxIndex, + payload.level + ) + ) + mixerGenericConnection.updateAuxLevel( + payload.channel, + payload.auxIndex + ) + this.updateFullClientStore() + remoteConnections.updateRemoteAuxPanels() + }) + .on(IO.SOCKET_SET_FX, (payload: any) => { + logger.trace( + `Set ${fxParamsList[payload.fxParam]}: ${payload.channel}` + ) + store.dispatch( + FADER_ACTIONS.storeFaderFx( + payload.fxParam, + payload.channel, + payload.level + ) + ) + mixerGenericConnection.updateFx( + payload.fxParam, + payload.channel + ) + this.updatePartialStore(payload.channel) + }) + .on(IO.SOCKET_NEXT_MIX, () => { + store.dispatch(FADER_ACTIONS.storeNextMix()) + mixerGenericConnection.updateOutLevels() + this.updateFullClientStore() + }) + .on(IO.SOCKET_CLEAR_PST, () => { + store.dispatch(FADER_ACTIONS.storeClearPst()) + mixerGenericConnection.updateOutLevels() + this.updateFullClientStore() + }) + .on(IO.SOCKET_TOGGLE_PGM, (faderIndex: any) => { + mixerGenericConnection.checkForAutoResetThreshold(faderIndex) + store.dispatch(FADER_ACTIONS.storeTogglePgm(faderIndex)) + mixerGenericConnection.updateOutLevel(faderIndex, -1) + this.updatePartialStore(faderIndex) + }) + .on(IO.SOCKET_TOGGLE_VO, (faderIndex: any) => { + mixerGenericConnection.checkForAutoResetThreshold(faderIndex) + store.dispatch(FADER_ACTIONS.storeToggleVo(faderIndex)) + mixerGenericConnection.updateOutLevel(faderIndex, -1) + this.updatePartialStore(faderIndex) + }) + .on(IO.SOCKET_TOGGLE_SLOW_FADE, (faderIndex: any) => { + store.dispatch(FADER_ACTIONS.storeToggleSlowFade(faderIndex)) + this.updatePartialStore(faderIndex) + }) + .on(IO.SOCKET_TOGGLE_PST, (faderIndex: any) => { + store.dispatch(FADER_ACTIONS.storeTogglePst(faderIndex)) + mixerGenericConnection.updateNextAux(faderIndex) + this.updatePartialStore(faderIndex) + }) + .on(IO.SOCKET_TOGGLE_PFL, (faderIndex: any) => { + store.dispatch(FADER_ACTIONS.storeTogglePfl(faderIndex)) + mixerGenericConnection.updatePflState(faderIndex) + this.updatePartialStore(faderIndex) + }) + .on(IO.SOCKET_TOGGLE_MUTE, (faderIndex: any) => { + store.dispatch(FADER_ACTIONS.storeToggleMute(faderIndex)) + mixerGenericConnection.updateMuteState(faderIndex) + this.updatePartialStore(faderIndex) + }) + .on(IO.SOCKET_TOGGLE_AMIX, (faderIndex: any) => { + store.dispatch(FADER_ACTIONS.storeToggleAMix(faderIndex)) + mixerGenericConnection.updateAMixState(faderIndex) + this.updatePartialStore(faderIndex) + }) + .on(IO.SOCKET_TOGGLE_IGNORE, (faderIndex: any) => { + store.dispatch( + FADER_ACTIONS.storeToggleIgnoreAutomation(faderIndex) + ) + this.updatePartialStore(faderIndex) + }) + .on(IO.SOCKET_SET_FADERLEVEL, (payload: any) => { + logger.trace( + `Set fader level\n Channel: ${ + payload.faderIndex + 1 + }\n Level: ${payload.level}` + ) + store.dispatch( + FADER_ACTIONS.storeFaderLevel( + payload.faderIndex, + parseFloat(payload.level) + ) + ) + mixerGenericConnection.updateOutLevel(payload.faderIndex, 0) + mixerGenericConnection.updateNextAux(payload.faderIndex) + this.updatePartialStore(payload.faderIndex) + }) + .on(IO.SOCKET_SET_INPUT_GAIN, (payload: any) => { + logger.trace( + `Set fInput\n Gain Channel: ${ + payload.faderIndex + 1 + }\n Level: ${payload.level}` + ) + store.dispatch( + FADER_ACTIONS.storeInputGain( + payload.faderIndex, + parseFloat(payload.level) + ) + ) + mixerGenericConnection.updateInputGain(payload.faderIndex) + this.updatePartialStore(payload.faderIndex) + }) + .on(IO.SOCKET_SET_INPUT_SELECTOR, (payload: any) => { + logger.trace( + `Set Input selector: ${ + payload.faderIndex + 1 + }\n Selected: ${payload.selected}` + ) + logger.debug(payload) + store.dispatch( + FADER_ACTIONS.storeInputSelector( + payload.faderIndex, + parseFloat(payload.selected) + ) + ) + mixerGenericConnection.updateInputSelector(payload.faderIndex) + this.updatePartialStore(payload.faderIndex) + }) + .on(IO.SOCKET_TOGGLE_ALL_MANUAL, () => { + logger.trace('Toggle manual mode for all') + store.dispatch(FADER_ACTIONS.storeAllManual()) + this.updateFullClientStore() + }) + .on(IO.SOCKET_SET_LABELS, (payload: any) => { + store.dispatch(FADER_ACTIONS.updateLabels(payload.update)) + }) + .on(IO.SOCKET_GET_LABELS, () => { + socketServer.emit( + IO.SOCKET_GET_LABELS, + state.faders[0].fader.map((f) => f.userLabel) + ) + }) + .on(IO.SOCKET_FLUSH_LABELS, () => { + store.dispatch(FADER_ACTIONS.flushExtLabels()) + store.dispatch(storeFlushChLabels()) + }) + } +} diff --git a/server/src/expressHandler.ts b/server/src/expressHandler.ts new file mode 100644 index 00000000..2dde4c22 --- /dev/null +++ b/server/src/expressHandler.ts @@ -0,0 +1,38 @@ +import { logger } from './utils/logger' +import { socketSubscribeVu, socketUnsubscribeVu } from './utils/vuServer' + +import express from 'express' +import path from 'path' +import { Server } from 'http' +import { Server as SocketServer } from 'socket.io' +const app = express() +const server = new Server(app) +const socketServer = new SocketServer(server) +const SERVER_PORT = 1176 +const staticPath = path.join( + path.dirname(require.resolve('client/package.json')), + 'dist' +) +logger.data(staticPath).debug('Express static file path:') +app.use('/', express.static(staticPath)) +server.listen(SERVER_PORT) +logger.info(`Server started at http://localhost:${SERVER_PORT}`) + +socketServer.on('connection', (socket: any) => { + logger.info(`Client connected: ${socket.client.id}`) + global.mainThreadHandler.socketServerHandlers(socket) + + socket.on('subscribe-vu-meter', () => { + logger.debug('Socket subscribe vu') + socketSubscribeVu(socket) + }) + socket.on('disconnect', () => { + socketUnsubscribeVu(socket) + }) +}) + +export const expressInit = () => { + logger.info('Initialising WebServer') +} + +export { socketServer } diff --git a/server/src/mainClasses.ts b/server/src/mainClasses.ts new file mode 100644 index 00000000..1ab29247 --- /dev/null +++ b/server/src/mainClasses.ts @@ -0,0 +1,22 @@ +import { + MixerProtocolPresets, + MixerProtocolList, +} from '../../shared/src/constants/MixerProtocolPresets' +import { MixerGenericConnection } from './utils/MixerConnection' +import { AutomationConnection } from './utils/AutomationConnection' +import { RemoteConnection } from './utils/RemoteConnection' + +const mixerProtocolPresets = MixerProtocolPresets +const mixerProtocolList = MixerProtocolList + +const mixerGenericConnection = new MixerGenericConnection() +const automationConnection = new AutomationConnection() +const remoteConnections = new RemoteConnection() + +export { + mixerProtocolList, + mixerProtocolPresets, + mixerGenericConnection, + automationConnection, + remoteConnections, +} diff --git a/server/src/reducers/store.ts b/server/src/reducers/store.ts new file mode 100644 index 00000000..1fe40f83 --- /dev/null +++ b/server/src/reducers/store.ts @@ -0,0 +1,14 @@ +import storeRedux from '../../../shared/src/reducers/store' +import { storeUpdateSettings } from '../../../shared/src/actions/settingsActions' +import { loadSettings } from '../utils/SettingsStorage' + +storeRedux.dispatch(storeUpdateSettings(loadSettings(storeRedux.getState()))) + +//Subscribe to redux store: +let state = storeRedux.getState() +const unsubscribe = storeRedux.subscribe(() => { + state = storeRedux.getState() +}) + +export { storeRedux as store } +export { state } \ No newline at end of file diff --git a/server/src/utils/AutomationConnection.ts b/server/src/utils/AutomationConnection.ts new file mode 100644 index 00000000..c10dd44f --- /dev/null +++ b/server/src/utils/AutomationConnection.ts @@ -0,0 +1,332 @@ +//Node Modules: +import osc from 'osc' +import { store, state } from '../reducers/store' +import { mixerGenericConnection } from '../mainClasses' + +//Utils: +import { + IAutomationProtocol, + AutomationPresets, +} from '../../../shared/src/constants/AutomationPresets' +import { IFader } from '../../../shared/src/reducers/fadersReducer' +import { + SNAP_RECALL, + storeFaderLevel, + storeFaderLabel, + storeSetPgm, + storeSetVo, + storeSetPstVo, + storeSetMute, + storeSetPst, + storeShowChannel, + storeXmix, + storeFadeToBlack, + storeClearPst, +} from '../../../shared/src/actions/faderActions' +import { getFaderLabel } from './labels' +import { logger } from './logger' + +const AUTOMATION_OSC_PORT = 5255 +export class AutomationConnection { + oscConnection: any + automationProtocol: IAutomationProtocol + + constructor() { + this.sendOutMessage = this.sendOutMessage.bind(this) + + this.automationProtocol = AutomationPresets.sofie + + this.oscConnection = new osc.UDPPort({ + localAddress: '0.0.0.0', + localPort: AUTOMATION_OSC_PORT, + }) + this.setupAutomationConnection() + } + + setupAutomationConnection() { + const messageHandler = ( + message: any, + timetag: number | undefined, + info: any + ) => { + const check = (key: keyof IAutomationProtocol['fromAutomation']) => + this.checkOscCommand( + message.address, + this.automationProtocol.fromAutomation[key] + ) + const wrapChannelCommand = (fn: (ch: any) => void) => { + let ch: number + let chMessage = message.address.split('/')[2] + + if (Number.isNaN(parseInt(chMessage))) { + // look among labels to find channel + const fader = state.faders[0].fader + .map((f, i) => ({ ...f, i })) + .find( + (f) => + f.userLabel === chMessage || + f.label === chMessage + ) + const channel = state.channels[0].chMixerConnection + .map((conn) => + conn.channel.map((ch) => ({ + assignedFader: ch.assignedFader, + label: ch.label, + })) + ) + .map((m) => m.find((ch) => ch.label === chMessage)) + .find((m) => m) + + if (fader) { + ch = fader.i + 1 + } else if (channel) { + ch = channel.assignedFader + 1 + } else { + logger.error( + `Could not find fader with label: ${chMessage}` + ) + return + } + } else { + ch = parseInt(chMessage) + } + + if ( + state.faders[0].fader[ch - 1] && + !state.faders[0].fader[ch - 1].ignoreAutomation + ) { + fn(ch) + } + global.mainThreadHandler.updatePartialStore(ch - 1) + } + + logger.data(message).debug(`RECIEVED AUTOMATION MESSAGE: ${message.address}`) + + // Set state of Sisyfos: + if (check('CHANNEL_PGM_ON_OFF')) { + wrapChannelCommand((ch: any) => { + if (message.args[0] === 1) { + mixerGenericConnection.checkForAutoResetThreshold( + ch - 1 + ) + store.dispatch(storeSetPgm(ch - 1, true)) + } else if (message.args[0] === 2) { + mixerGenericConnection.checkForAutoResetThreshold( + ch - 1 + ) + store.dispatch(storeSetVo(ch - 1, true)) + } else { + store.dispatch(storeSetPgm(ch - 1, false)) + } + + if (message.args.length > 1) { + mixerGenericConnection.updateOutLevel( + ch - 1, + parseFloat(message.args[1]) + ) + } else { + mixerGenericConnection.updateOutLevel(ch - 1, -1) + } + }) + } else if (check('CHANNEL_PST_ON_OFF')) { + wrapChannelCommand((ch) => { + if (message.args[0] === 1) { + store.dispatch(storeSetPst(ch - 1, true)) + } else if (message.args[0] === 2) { + store.dispatch(storeSetPstVo(ch - 1, true)) + } else { + store.dispatch(storeSetPst(ch - 1, false)) + } + mixerGenericConnection.updateNextAux(ch - 1) + }) + } else if (check('CHANNEL_MUTE')) { + wrapChannelCommand((ch: any) => { + store.dispatch(storeSetMute(ch - 1, message.args[0] === 1)) + mixerGenericConnection.updateMuteState(ch - 1) + }) + } else if (check('CHANNEL_FADER_LEVEL')) { + wrapChannelCommand((ch: any) => { + store.dispatch(storeFaderLevel(ch - 1, message.args[0])) + mixerGenericConnection.updateOutLevel(ch - 1, -1) + global.mainThreadHandler.updatePartialStore(ch - 1) + }) + } else if (check('INJECT_COMMAND')) { + wrapChannelCommand((ch: any) => { + store.dispatch(storeFaderLabel(ch - 1, message.args[0])) + mixerGenericConnection.injectCommand(message.args) + }) + } else if (check('SNAP_RECALL')) { + let snapNumber = message.address.split('/')[2] + store.dispatch({ + type: SNAP_RECALL, + snapIndex: snapNumber - 1, + }) + } else if (check('SET_LABEL')) { + wrapChannelCommand((ch: any) => { + store.dispatch(storeFaderLabel(ch - 1, message.args[0])) + mixerGenericConnection.updateChannelName(ch - 1) + }) + } else if (check('X_MIX')) { + store.dispatch(storeXmix()) + mixerGenericConnection.updateOutLevels() + global.mainThreadHandler.updateFullClientStore() + } else if (check('CHANNEL_VISIBLE')) { + wrapChannelCommand((ch: any) => { + store.dispatch( + storeShowChannel(ch - 1, message.args[0] === 1) + ) + }) + } else if (check('FADE_TO_BLACK')) { + store.dispatch(storeFadeToBlack()) + mixerGenericConnection.updateFadeToBlack() + global.mainThreadHandler.updateFullClientStore() + } else if (check('CLEAR_PST')) { + store.dispatch(storeClearPst()) + mixerGenericConnection.updateOutLevels() + global.mainThreadHandler.updateFullClientStore() + } else if (check('STATE_FULL')) { + // Get state from Producers Audio Mixer: + this.sendOutMessage( + this.automationProtocol.toAutomation.STATE_FULL, + 0, + JSON.stringify({ + channel: state.faders[0].fader.map( + ( + { + faderLevel, + pgmOn, + voOn, + pstOn, + showChannel, + }: IFader, + index + ) => ({ + faderLevel, + pgmOn, + voOn, + pstOn, + showChannel, + label: getFaderLabel(index), + }) + ), + }), + 's', + info + ) + } else if (check('STATE_CHANNEL_PGM')) { + wrapChannelCommand((ch: any) => { + this.sendOutMessage( + this.automationProtocol.toAutomation.STATE_CHANNEL_PGM, + ch, + state.faders[0].fader[ch - 1].pgmOn, + 'i', + info + ) + }) + } else if (check('STATE_CHANNEL_PST')) { + wrapChannelCommand((ch) => { + this.sendOutMessage( + this.automationProtocol.toAutomation.STATE_CHANNEL_PST, + ch, + state.faders[0].fader[ch - 1].pstOn, + 'i', + info + ) + }) + } else if (check('STATE_CHANNEL_MUTE')) { + wrapChannelCommand((ch) => { + this.sendOutMessage( + this.automationProtocol.toAutomation.STATE_CHANNEL_MUTE, + ch, + state.faders[0].fader[ch - 1].muteOn, + 'i', + info + ) + }) + } else if (check('STATE_CHANNEL_FADER_LEVEL')) { + wrapChannelCommand((ch) => { + this.sendOutMessage( + this.automationProtocol.toAutomation + .STATE_CHANNEL_FADER_LEVEL, + ch, + state.faders[0].fader[ch - 1].faderLevel, + 'f', + info + ) + }) + } else if (check('PING')) { + let pingValue = state.settings[0].mixers[0].mixerOnline + ? message.address.split('/')[2] + : 'offline' + + this.sendOutMessage( + this.automationProtocol.toAutomation.PONG, + 0, + pingValue, + 's', + info + ) + } + } + + this.oscConnection + .on('ready', () => { + this.automationProtocol.initializeCommands.map((item) => { + // this.sendOutMessage(item.oscMessage, 1, item.value, item.type); + logger.info('Listening for Automation via OSC over UDP.') + }) + }) + .on('message', messageHandler) + .on('error', (error: any) => { + logger.data(error).error('Error OSC') + }) + + this.oscConnection.open() + logger.info(`OSC Automation listening on port ${AUTOMATION_OSC_PORT}`) + } + + checkOscCommand(message: string, command: string) { + if (message === command) return true + + let cmdArray = command.split('{value1}') + + if ( + message.substr(0, cmdArray[0].length) === cmdArray[0] && + (message.substr(-cmdArray[1].length) === cmdArray[1] || + cmdArray[1].length === 0) && + message.length >= command.replace('{value1}', '').length + ) { + return true + } else { + return false + } + } + + sendOutMessage( + oscMessage: string, + channel: number, + value: string | number | boolean, + type: string, + to: { address: string; port: number } + ) { + let channelString = this.automationProtocol.leadingZeros + ? ('0' + channel).slice(-2) + : channel.toString() + let message = oscMessage.replace('{value1}', channelString) + if (message != 'none') { + this.oscConnection.send( + { + address: message, + args: [ + { + type: type, + value: value, + }, + ], + }, + to.address, + to.port + ) + } + } +} diff --git a/server/src/utils/MixerConnection.ts b/server/src/utils/MixerConnection.ts new file mode 100644 index 00000000..d369306e --- /dev/null +++ b/server/src/utils/MixerConnection.ts @@ -0,0 +1,559 @@ +import { store, state } from '../reducers/store' +import { logger } from './logger' +import { remoteConnections } from '../mainClasses' + +//Utils: +import { MixerProtocolPresets } from '../../../shared/src/constants/MixerProtocolPresets' +import { + IMixerProtocol, + IMixerProtocolGeneric, + ICasparCGMixerGeometry, + fxParamsList, +} from '../../../shared/src/constants/MixerProtocolInterface' +import { OscMixerConnection } from './mixerConnections/OscMixerConnection' +import { VMixMixerConnection } from './mixerConnections/VMixMixerConnection' +import { MidiMixerConnection } from './mixerConnections/MidiMixerConnection' +import { QlClMixerConnection } from './mixerConnections/YamahaQlClConnection' +import { SSLMixerConnection } from './mixerConnections/SSLMixerConnection' +import { EmberMixerConnection } from './mixerConnections/EmberMixerConnection' +import { LawoRubyMixerConnection } from './mixerConnections/LawoRubyConnection' +import { StuderMixerConnection } from './mixerConnections/StuderMixerConnection' +import { StuderVistaMixerConnection } from './mixerConnections/StuderVistaMixerConnection' +import { CasparCGConnection } from './mixerConnections/CasparCGConnection' +import { + IChannel, + IchMixerConnection, +} from '../../../shared/src/reducers/channelsReducer' +import { + storeFadeActive, + storeSetOutputLevel, +} from '../../../shared/src/actions/channelActions' +import { storeFaderLevel } from '../../../shared/src/actions/faderActions' +import { AtemMixerConnection } from './mixerConnections/AtemConnection' + +export class MixerGenericConnection { + store: any + mixerProtocol: IMixerProtocolGeneric[] + mixerConnection: any[] + mixerTimers: { + chTimer: NodeJS.Timeout[] + fadeActiveTimer: NodeJS.Timeout[] + }[] + + constructor() { + this.mixerProtocol = [] + this.mixerConnection = [] + // Get mixer protocol + state.settings[0].mixers.forEach((none: any, index: number) => { + this.mixerProtocol.push( + MixerProtocolPresets[ + state.settings[0].mixers[index].mixerProtocol + ] || MixerProtocolPresets.sslSystemT + ) + this.mixerConnection.push({}) + if (this.mixerProtocol[index].protocol === 'OSC') { + this.mixerConnection[index] = new OscMixerConnection( + this.mixerProtocol[index] as IMixerProtocol, + index + ) + } else if (this.mixerProtocol[index].protocol === 'QLCL') { + this.mixerConnection[index] = new QlClMixerConnection( + this.mixerProtocol[index] as IMixerProtocol, + index + ) + } else if (this.mixerProtocol[index].protocol === 'MIDI') { + this.mixerConnection[index] = new MidiMixerConnection( + this.mixerProtocol[index] as IMixerProtocol, + index + ) + } else if (this.mixerProtocol[index].protocol === 'CasparCG') { + this.mixerConnection[index] = new CasparCGConnection( + this.mixerProtocol[index] as ICasparCGMixerGeometry, + index + ) + } else if (this.mixerProtocol[index].protocol === 'EMBER') { + this.mixerConnection[index] = new EmberMixerConnection( + this.mixerProtocol[index] as IMixerProtocol, + index + ) + } else if (this.mixerProtocol[index].protocol === 'LAWORUBY') { + this.mixerConnection[index] = new LawoRubyMixerConnection( + this.mixerProtocol[index] as IMixerProtocol, + index + ) + } else if (this.mixerProtocol[index].protocol === 'STUDER') { + this.mixerConnection[index] = new StuderMixerConnection( + this.mixerProtocol[index] as IMixerProtocol, + index + ) + } else if (this.mixerProtocol[index].protocol === 'VISTA') { + this.mixerConnection[index] = new StuderVistaMixerConnection( + this.mixerProtocol[index] as IMixerProtocol, + index + ) + } else if (this.mixerProtocol[index].protocol === 'SSL') { + this.mixerConnection[index] = new SSLMixerConnection( + this.mixerProtocol[index] as IMixerProtocol, + index + ) + } else if (this.mixerProtocol[index].protocol === 'VMIX') { + this.mixerConnection[index] = new VMixMixerConnection( + this.mixerProtocol[index] as IMixerProtocol, + index + ) + } else if (this.mixerProtocol[index].protocol === 'ATEM') { + this.mixerConnection[index] = new AtemMixerConnection( + this.mixerProtocol[index], + index + ) + } + }) + + // Setup timers for fade in & out + this.initializeTimers() + } + + initializeTimers = () => { + // Setup timers for fade in & out + this.mixerTimers = [] + state.channels[0].chMixerConnection.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + this.mixerTimers.push({ chTimer: [], fadeActiveTimer: [] }) + state.channels[0].chMixerConnection[mixerIndex].channel.forEach( + (channel) => { + this.mixerTimers[mixerIndex].chTimer.push(undefined) + this.mixerTimers[mixerIndex].fadeActiveTimer.push( + undefined + ) + } + ) + } + ) + } + + clearTimer = (mixerIndex: number, channelIndex: number) => { + if (this.mixerTimers[mixerIndex]?.chTimer[channelIndex]) { + clearInterval(this.mixerTimers[mixerIndex].chTimer[channelIndex]) + } + } + + delayedFadeActiveDisable = (mixerIndex: number, channelIndex: number) => { + this.mixerTimers[mixerIndex].fadeActiveTimer[channelIndex] = setTimeout( + () => { + store.dispatch(storeFadeActive(mixerIndex, channelIndex, false)) + }, + state.settings[0].mixers[0].protocolLatency + ) + } + + getPresetFileExtention = (): string => { + //TODO: atm mixer presets only supports first mixer connected to Sisyfos + return this.mixerProtocol[0].presetFileExtension || '' + } + + loadMixerPreset = (presetName: string) => { + //TODO: atm mixer presets only supports first mixer connected to Sisyfos + this.mixerConnection[0].loadMixerPreset(presetName) + } + + checkForAutoResetThreshold = (channel: number) => { + if ( + state.faders[0].fader[channel].faderLevel <= + state.settings[0].autoResetLevel / 100 + ) { + store.dispatch( + storeFaderLevel(channel, this.mixerProtocol[0].fader.zero) + ) + } + } + + updateFadeToBlack = () => { + state.faders[0].fader.forEach((channel: any, index: number) => { + this.updateOutLevel(index, -1) + }) + } + + updateOutLevels = () => { + state.faders[0].fader.forEach((channel: any, index: number) => { + this.updateOutLevel(index, -1) + this.updateNextAux(index) + }) + } + + updateOutLevel = ( + faderIndex: number, + fadeTime: number, + mixerIndexToSkip: number = -1 + ) => { + if (fadeTime === -1) { + if (state.faders[0].fader[faderIndex].voOn) { + fadeTime = state.settings[0].voFadeTime + } else { + fadeTime = state.settings[0].fadeTime + + // When in manual mode - test if SLOW FADE Button is ON: + if ( + !state.settings[0].automationMode && + state.faders[0].fader[faderIndex].slowFadeOn + ) { + fadeTime = state.settings[0].voFadeTime + } + } + } + + state.channels[0].chMixerConnection.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + if (mixerIndex !== mixerIndexToSkip) { + chMixerConnection.channel.forEach( + (channel: IChannel, channelIndex: number) => { + if (faderIndex === channel.assignedFader) { + this.fadeInOut( + mixerIndex, + channelIndex, + fadeTime + ) + } + } + ) + } + } + ) + + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + faderIndex, + state.faders[0].fader[faderIndex].faderLevel + ) + } + } + + updateInputGain = (faderIndex: number) => { + let level = state.faders[0].fader[faderIndex].inputGain + state.channels[0].chMixerConnection.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + chMixerConnection.channel.forEach( + (channel: IChannel, channelIndex: number) => { + if (faderIndex === channel.assignedFader) { + this.mixerConnection[mixerIndex].updateInputGain( + channelIndex, + level + ) + } + } + ) + } + ) + } + + updateInputSelector = (faderIndex: number) => { + let inputSelected = state.faders[0].fader[faderIndex].inputSelector + logger.trace(`${faderIndex} ${inputSelected}`) + state.channels[0].chMixerConnection.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + chMixerConnection.channel.forEach( + (channel: IChannel, channelIndex: number) => { + if (faderIndex === channel.assignedFader) { + this.mixerConnection[ + mixerIndex + ].updateInputSelector(channelIndex, inputSelected) + } + } + ) + } + ) + } + + updatePflState = (channelIndex: number) => { + this.mixerConnection[0].updatePflState(channelIndex) + } + + updateMuteState = (faderIndex: number, mixerIndexToSkip: number = -1) => { + state.channels[0].chMixerConnection.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + if (mixerIndex !== mixerIndexToSkip) { + chMixerConnection.channel.forEach( + (channel: IChannel, channelIndex: number) => { + if (faderIndex === channel.assignedFader) { + this.mixerConnection[ + mixerIndex + ].updateMuteState( + channelIndex, + state.faders[0].fader[faderIndex].muteOn + ) + } + } + ) + } + } + ) + } + + updateAMixState = (faderIndex: number) => { + state.channels[0].chMixerConnection.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + chMixerConnection.channel.forEach( + (channel: IChannel, channelIndex: number) => { + if (faderIndex === channel.assignedFader) { + this.mixerConnection[mixerIndex].updateAMixState( + channelIndex, + state.faders[0].fader[faderIndex].amixOn + ) + } + } + ) + } + ) + } + + updateNextAux = (faderIndex: number) => { + let level = 0 + if (state.faders[0].fader[faderIndex].pstOn) { + level = state.faders[0].fader[faderIndex].faderLevel + } else if (state.faders[0].fader[faderIndex].pstVoOn) { + level = + (state.faders[0].fader[faderIndex].faderLevel * + (100 - state.settings[0].voLevel)) / + 100 + } + state.channels[0].chMixerConnection.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + chMixerConnection.channel.forEach( + (channel: IChannel, channelIndex: number) => { + if (faderIndex === channel.assignedFader) { + this.mixerConnection[mixerIndex].updateNextAux( + channelIndex, + level + ) + } + } + ) + } + ) + } + + updateFx = (fxParam: fxParamsList, faderIndex: number) => { + let level: number = state.faders[0].fader[faderIndex][fxParam][0] + state.channels[0].chMixerConnection.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + chMixerConnection.channel.forEach( + (channel: IChannel, channelIndex: number) => { + if (faderIndex === channel.assignedFader) { + this.mixerConnection[mixerIndex].updateFx( + fxParam, + channelIndex, + level + ) + } + } + ) + } + ) + } + updateAuxLevel = (channelIndex: number, auxSendIndex: number) => { + let channel = + state.channels[0].chMixerConnection[0].channel[channelIndex] + if (channel.auxLevel[auxSendIndex] > -1) { + this.mixerConnection[0].updateAuxLevel( + channelIndex, + auxSendIndex, + channel.auxLevel[auxSendIndex] + ) + } + } + + updateChannelName = (channelIndex: number) => { + this.mixerConnection[0].updateChannelName(channelIndex) + } + + injectCommand = (command: string[]) => { + this.mixerConnection[0].injectCommand(command) + } + + updateChannelSettings = ( + channelIndex: number, + setting: string, + value: string + ) => { + if (this.mixerProtocol[0].protocol === 'CasparCG') { + this.mixerConnection[0].updateChannelSetting( + channelIndex, + setting, + value + ) + } + } + + fadeInOut = ( + mixerIndex: number, + channelIndex: number, + fadeTime: number + ) => { + let faderIndex = + state.channels[0].chMixerConnection[mixerIndex].channel[ + channelIndex + ].assignedFader + if ( + !state.faders[0].fader[faderIndex].pgmOn && + !state.faders[0].fader[faderIndex].voOn && + state.channels[0].chMixerConnection[mixerIndex].channel[ + channelIndex + ].outputLevel === 0 + ) { + return + } + if ( + this.mixerTimers.length === 1 && + this.mixerTimers[0].chTimer.length === 1 + ) { + this.initializeTimers() + } + //Clear Old timer or set Fade to active: + if ( + state.channels[0].chMixerConnection[mixerIndex].channel[ + channelIndex + ].fadeActive + ) { + clearInterval( + this.mixerTimers[mixerIndex].fadeActiveTimer[channelIndex] + ) + this.clearTimer(mixerIndex, channelIndex) + } + store.dispatch(storeFadeActive(mixerIndex, channelIndex, true)) + if ( + state.faders[0].fader[faderIndex].pgmOn || + state.faders[0].fader[faderIndex].voOn + ) { + this.fadeUp(mixerIndex, channelIndex, fadeTime, faderIndex) + } else { + this.fadeDown(mixerIndex, channelIndex, fadeTime) + } + } + + fadeUp = ( + mixerIndex: number, + channelIndex: number, + fadeTime: number, + faderIndex: number + ) => { + const outputLevel = + state.channels[0].chMixerConnection[mixerIndex].channel[ + channelIndex + ].outputLevel + let targetVal = state.faders[0].fader[faderIndex].faderLevel + + if (state.faders[0].fader[faderIndex].voOn) { + targetVal = (targetVal * (100 - state.settings[0].voLevel)) / 100 + } + + this.fade(fadeTime, mixerIndex, channelIndex, outputLevel, targetVal) + } + + fade( + fadeTime: number, + mixerIndex: number, + channelIndex: number, + startLevel: number, + endLevel: number + ) { + const startTimeAsMs = Date.now() + const updateInterval: number = Math.floor( + 1000 / this.mixerProtocol[mixerIndex].MAX_UPDATES_PER_SECOND + ) + + this.clearTimer(mixerIndex, channelIndex) + + this.mixerTimers[mixerIndex].chTimer[channelIndex] = setInterval( + () => + this.updateOutputLevel( + startTimeAsMs, + fadeTime, + mixerIndex, + channelIndex, + startLevel, + endLevel + ), + updateInterval + ) + this.updateOutputLevel( + startTimeAsMs, + fadeTime, + mixerIndex, + channelIndex, + startLevel, + endLevel + ) + } + + private updateOutputLevel( + startTimeAsMs: number, + fadeTime: number, + mixerIndex: number, + channelIndex: number, + startLevel: number, + endLevel: number + ) { + const currentTimeMS = Date.now() + const elapsedTimeMS = currentTimeMS - startTimeAsMs + + if (elapsedTimeMS >= fadeTime) { + this.mixerConnection[mixerIndex].updateFadeIOLevel( + channelIndex, + endLevel + ) + this.clearTimer(mixerIndex, channelIndex) + store.dispatch( + storeSetOutputLevel(mixerIndex, channelIndex, endLevel) + ) + this.delayedFadeActiveDisable(mixerIndex, channelIndex) + return true + } + + const currentOutputLevel = + startLevel + + (endLevel - startLevel) * + Math.max(0, Math.min(1, elapsedTimeMS / fadeTime)) + + this.mixerConnection[mixerIndex].updateFadeIOLevel( + channelIndex, + currentOutputLevel + ) + + store.dispatch( + storeSetOutputLevel(mixerIndex, channelIndex, currentOutputLevel) + ) + } + + fadeDown = (mixerIndex: number, channelIndex: number, fadeTime: number) => { + const outputLevel = + state.channels[0].chMixerConnection[mixerIndex].channel[ + channelIndex + ].outputLevel + + this.fade(fadeTime, mixerIndex, channelIndex, outputLevel, 0) + } +} + +export interface MixerConnection { + updatePflState: (channelIndex: number) => void + updateMuteState: (channelIndex: number, muteOn: boolean) => void + updateAMixState: (channelIndex: number, amixOn: boolean) => void + updateNextAux: (channelIndex: number, level: number) => void + updateFx: ( + fxParam: fxParamsList, + channelIndex: number, + level: number + ) => void + updateAuxLevel: ( + channelIndex: number, + auxSendIndex: number, + auxLevel: number + ) => void + updateChannelName: (channelIndex: number) => void + injectCommand: (command: string[]) => void + updateChannelSetting: ( + channelIndex: number, + setting: string, + value: string + ) => void + updateFadeIOLevel: (channelIndex: number, level: number) => void +} diff --git a/server/src/utils/RemoteConnection.ts b/server/src/utils/RemoteConnection.ts new file mode 100644 index 00000000..865c6434 --- /dev/null +++ b/server/src/utils/RemoteConnection.ts @@ -0,0 +1,30 @@ +import { HuiMidiRemoteConnection } from './remoteConnections/HuiMidiRemoteConnection' +import { SkaarhojRemoteConnection } from './remoteConnections/SkaarhojRemoteConnection' + +export class RemoteConnection { + store: any + remoteConnection: any + + constructor() { + // HUI SUPPORT IS DISABLED AND SKAARHOJ IS ALWAYS ON + // HUI needs to be updated so for now it´s always disabled. + this.remoteConnection = new SkaarhojRemoteConnection() + /* + if (state.settings[0].enableRemoteFader) { + this.remoteConnection = new HuiMidiRemoteConnection() + } + */ + } + + updateRemoteFaderState(channelIndex: number, outputLevel: number) { + this.remoteConnection.updateRemoteFaderState(channelIndex, outputLevel) + } + + updateRemoteAuxPanels() { + this.remoteConnection.updateRemoteAuxPanels() + } + + updateRemotePgmPstPfl(channelIndex: number) { + this.remoteConnection.updateRemotePgmPstPfl(channelIndex) + } +} diff --git a/server/src/utils/SettingsStorage.ts b/server/src/utils/SettingsStorage.ts new file mode 100644 index 00000000..8be462c0 --- /dev/null +++ b/server/src/utils/SettingsStorage.ts @@ -0,0 +1,217 @@ +// Node Modules: +import fs from 'fs' +import path from 'path' +import { homedir, platform as getPlatform } from 'os' +const platform = getPlatform() +const homeDir = homedir() + +import { store } from '../reducers/store' +import { checkVersion } from './migrations' + +// Redux: +import { storeSetCompleteChState } from '../../../shared/src/actions/channelActions' +import { storeSetCompleteFaderState } from '../../../shared/src/actions/faderActions' +import { logger } from './logger' +import { defaultFadersReducerState } from '../../../shared/src/reducers/fadersReducer' + +import { + IChannels, + InumberOfChannels, +} from '../../../shared/src/reducers/channelsReducer' + +import { + ICustomPages, + ISettings, +} from '../../../shared/src/reducers/settingsReducer' +import { IFaders } from '../../../shared/src/reducers/fadersReducer' + +export interface IShotStorage { + channelState: IChannels + faderState: IFaders +} + +// Linux place in "app"/storage to be backward compatible with Docker containers. +// Windows and Mac place the storagefolder in home -> sisyfos-storage +export const STORAGE_FOLDER = (platform === 'linux') ? + path.resolve(process.cwd(), 'storage') : + path.resolve(homeDir, 'sisyfos-storage') + + +export const loadSettings = (storeRedux: any): ISettings => { + let newSettings = storeRedux.settings[0] + try { + newSettings = JSON.parse( + fs.readFileSync( + path.resolve(STORAGE_FOLDER, 'settings.json'), + 'utf8' + ) + ) + checkVersion(newSettings) + return newSettings + } catch (error) { + logger + .data(error) + .error('Couldn´t read Settings.json file, creating af new') + saveSettings(newSettings) + return newSettings + } +} + +export const saveSettings = (settings: any) => { + const settingsCopy = { ...settings } + delete settingsCopy.customPages + let json = JSON.stringify(settingsCopy) + if (!fs.existsSync(STORAGE_FOLDER)) { + fs.mkdirSync(STORAGE_FOLDER) + } + fs.writeFile( + path.resolve(STORAGE_FOLDER, 'settings.json'), + json, + 'utf8', + (error: any) => { + if (error) { + logger.data(error).error('Error writing settings.json file: ') + } + } + ) +} + +export const loadSnapshotState = ( + stateSnapshot: IFaders, + stateChannelSnapshot: IChannels, + numberOfChannels: InumberOfChannels[], + numberOfFaders: number, + fileName: string, + loadAll: boolean +) => { + try { + const stateFromFile: IShotStorage = JSON.parse( + fs.readFileSync(fileName, 'utf8') + ) + + if (loadAll) { + store.dispatch( + storeSetCompleteChState( + stateFromFile.channelState as IChannels, + numberOfChannels + ) + ) + store.dispatch( + storeSetCompleteFaderState( + stateFromFile.faderState as IFaders, + numberOfFaders + ) + ) + } + } catch (error) { + if (fileName.includes('default.shot')) { + store.dispatch( + storeSetCompleteFaderState( + defaultFadersReducerState(numberOfFaders)[0], + numberOfFaders + ) + ) + logger.data(error).error('Initializing empty faders') + } else { + logger.data(error).error('Error loading Snapshot') + } + } +} + +export const saveSnapshotState = (stateSnapshot: any, fileName: string) => { + let json = JSON.stringify(stateSnapshot) + fs.writeFile(fileName, json, 'utf8', (error: any) => { + if (error) { + logger.data(error).error('Error saving Snapshot') + } else { + logger.trace('Snapshot ' + fileName + ' Saved to storage folder') + } + }) +} + +export const getSnapShotList = (): string[] => { + const files = fs + .readdirSync(path.resolve(STORAGE_FOLDER)) + .filter((file: string) => { + if (file.includes('.shot') && file !== 'default.shot') { + return true + } + }) + return files +} + +export const getMixerPresetList = (fileExtension: string): string[] => { + if (fileExtension === '') { + return [] + } + const files = fs + .readdirSync(path.resolve(STORAGE_FOLDER)) + .filter((file: string) => { + if ( + file.toUpperCase().includes('.' + fileExtension.toUpperCase()) + ) { + return true + } + }) + return files +} + +export const getCcgSettingsList = () => { + const files = fs + .readdirSync(path.resolve(STORAGE_FOLDER)) + .filter((file: string) => { + if (file.includes('.ccg') && file !== 'default-casparcg.ccg') { + return true + } + }) + return files +} + +export const setCcgDefault = (fileName: string) => { + let data: any + try { + data = fs.readFileSync(path.join(STORAGE_FOLDER, fileName)) + } catch (error) { + logger.error('Couldn´t read ' + fileName + ' file') + return + } + + const defaultFile = path.join(STORAGE_FOLDER, 'default-casparcg.ccg') + fs.writeFile(defaultFile, data, 'utf8', (error: any) => { + if (error) { + logger.data(error).error('Error setting default CasparCG setting') + } else { + logger.info('CasparCG' + fileName + ' Saved as default CasparCG') + } + }) +} + +export const getCustomPages = (): ICustomPages[] => { + try { + return JSON.parse( + fs.readFileSync(path.resolve(STORAGE_FOLDER, 'pages.json'), 'utf8') + ) + } catch (error) { + logger.error('Couldn´t read pages.json file') + return [] + } +} + +export const saveCustomPages = ( + stateCustomPages: any, + fileName: string = 'pages.json' +) => { + let json = JSON.stringify(stateCustomPages) + fs.writeFile( + path.join(STORAGE_FOLDER, fileName), + json, + 'utf8', + (error: any) => { + if (error) { + logger.data(error).error('Error saving pages file') + } else { + logger.info('Pages ' + fileName + ' Saved to storage folder') + } + } + ) +} diff --git a/server/src/utils/SnapshotHandler.ts b/server/src/utils/SnapshotHandler.ts new file mode 100644 index 00000000..52bdc612 --- /dev/null +++ b/server/src/utils/SnapshotHandler.ts @@ -0,0 +1,76 @@ +//Utils: +import { loadSnapshotState, saveSnapshotState } from './SettingsStorage' +import { mixerProtocolPresets } from '../mainClasses' +import { state } from '../reducers/store' +import { logger } from './logger' +import { InumberOfChannels } from '../../../shared/src/reducers/channelsReducer' +import { STORAGE_FOLDER } from './SettingsStorage' + +import path from 'path' +export class SnapshotHandler { + numberOfChannels: InumberOfChannels[] = [] + + constructor() { + logger.info('Setting up state') + + this.snapShopStoreTimer() + + // Count total number of channels: + for ( + let mixerIndex = 0; + mixerIndex < state.settings[0].numberOfMixers; + mixerIndex++ + ) { + this.numberOfChannels.push({ numberOfTypeInCh: [] }) + mixerProtocolPresets[ + state.settings[0].mixers[mixerIndex].mixerProtocol + ].channelTypes.forEach((item: any, index: number) => { + this.numberOfChannels[mixerIndex].numberOfTypeInCh.push( + state.settings[0].mixers[mixerIndex].numberOfChannelsInType[ + index + ] + ) + }) + } + this.loadSnapshotSettings( + path.resolve(STORAGE_FOLDER, 'default.shot'), + true + ) + + // ** UNCOMMENT TO DUMP A FULL STORE: + //const fs = require('fs') + //fs.writeFileSync('src/components/__tests__/__mocks__/parsedFullStore-UPDATE.json', JSON.stringify(global.storeRedux.getState())) + } + + snapShopStoreTimer() { + const saveTimer = setInterval(() => { + let snapshot = { + faderState: state.faders[0], + channelState: state.channels[0], + } + saveSnapshotState( + snapshot, + path.resolve(STORAGE_FOLDER, 'default.shot') + ) + }, 2000) + } + + loadSnapshotSettings(fileName: string, loadAll: boolean) { + loadSnapshotState( + state.faders[0], + state.channels[0], + this.numberOfChannels, + state.settings[0].numberOfFaders, + fileName, + loadAll + ) + } + + saveSnapshotSettings(fileName: string) { + let snapshot = { + faderState: state.faders[0], + channelState: state.channels[0], + } + saveSnapshotState(snapshot, fileName) + } +} diff --git a/server/src/utils/labels.ts b/server/src/utils/labels.ts new file mode 100644 index 00000000..29f25f30 --- /dev/null +++ b/server/src/utils/labels.ts @@ -0,0 +1,49 @@ +import { IStore } from '../../../shared/src/reducers/store' +import { state } from '../reducers/store' + +export function getChannelLabel( + state: IStore, + faderIndex: number +): string | undefined { + return state.channels[0].chMixerConnection + .map((conn) => + conn.channel.map((ch) => ({ + assignedFader: ch.assignedFader, + label: ch.label, + })) + ) + .reduce((a, b) => [...a, ...b], []) // flatten + .filter((ch) => ch.label && ch.label !== '') + .find((ch) => ch.assignedFader === faderIndex)?.label +} + +export function getFaderLabel(faderIndex: number, defaultName = 'CH'): string { + const automationLabel = + state.faders[0].fader[faderIndex] && + state.faders[0].fader[faderIndex].label !== '' + ? state.faders[0].fader[faderIndex].label + : undefined + const userLabel = + state.faders[0].fader[faderIndex] && + state.faders[0].fader[faderIndex].userLabel !== '' + ? state.faders[0].fader[faderIndex].userLabel + : undefined + const channelLabel = getChannelLabel(state, faderIndex) + + switch (state.settings[0].labelType) { + case 'automation': + return automationLabel || defaultName + ' ' + (faderIndex + 1) + case 'user': + return userLabel || defaultName + ' ' + (faderIndex + 1) + case 'channel': + return channelLabel || defaultName + ' ' + (faderIndex + 1) + case 'automatic': + default: + return ( + userLabel || + automationLabel || + channelLabel || + defaultName + ' ' + (faderIndex + 1) + ) + } +} diff --git a/server/src/utils/logger.ts b/server/src/utils/logger.ts new file mode 100644 index 00000000..3067b8ad --- /dev/null +++ b/server/src/utils/logger.ts @@ -0,0 +1,3 @@ +import { DefaultLogger } from '@tv2media/logger/node' + +export const logger = new DefaultLogger() diff --git a/server/src/utils/migrations.ts b/server/src/utils/migrations.ts new file mode 100644 index 00000000..1d8ac3f7 --- /dev/null +++ b/server/src/utils/migrations.ts @@ -0,0 +1,89 @@ +import fs from 'fs' +import path from 'path' + +import { logger } from './logger' +import { ISettings } from '../../../shared/src/reducers/settingsReducer' +import { getSnapShotList, IShotStorage } from './SettingsStorage' + +const version = process.env.npm_package_version +const settingsPath: string = path.resolve(process.cwd(), 'storage') + +export const checkVersion = (currentSettings: ISettings): ISettings => { + if ( + versionAsNumber(version) > + versionAsNumber(currentSettings.sisyfosVersion) + ) { + currentSettings = migrateVersion(currentSettings) + } + return currentSettings +} + +const migrateVersion = (currentSettings: ISettings): ISettings => { + logger.info( + `Migrating VERSION from ${currentSettings.sisyfosVersion} to ${version}` + ) + let newSettings = currentSettings + if (versionAsNumber(version) >= versionAsNumber('4.7.0')) { + newSettings = migrate45to47(currentSettings) + } + return newSettings +} + +const migrate45to47 = (currentSettings: ISettings): ISettings => { + let files: string[] = getSnapShotList() + files.push('default.shot') + + files.forEach((fileName: string) => { + let stateFromShot = JSON.parse( + fs.readFileSync(path.join(settingsPath, fileName), 'utf8') + ) + // As this is the first implemented migration it also looks .shot files from ealier versions than 4.xx + if (stateFromShot.channelState.chConnection) { + // From Version 4.xx + stateFromShot.channelState.chMixerConnection = + stateFromShot.channelState?.chConnection + delete stateFromShot.channelState.chConnection + } else if (stateFromShot.channelState.channel) { + // Version lower than 4.0 + stateFromShot.channelState.chMixerConnection = [ + { channel: stateFromShot.channelState.channel }, + ] + delete stateFromShot.channelState.channel + } + let migratedShot: IShotStorage = stateFromShot + try { + fs.writeFileSync( + path.join(settingsPath, fileName), + JSON.stringify(migratedShot), + 'utf8' + ) + logger.trace(`Snapshot ${fileName} Saved to storage folder`) + } catch (error: any) { + logger.data(error).error('Error saving Snapshot') + } + }) + currentSettings.sisyfosVersion = version + delete currentSettings.customPages + try { + fs.writeFileSync( + path.join(settingsPath, 'settings.json'), + JSON.stringify(currentSettings), + 'utf8' + ) + } catch (error: any) { + logger + .data(error) + .error('Migration failed - error writing settings.json file') + } + return currentSettings +} + +const versionAsNumber = (versionString: string): number => { + if (!versionString) return 0 + let versionArray: string[] = versionString.split('.') + let versionValue: number = + parseInt(versionArray[0]) * 10000 + + parseInt(versionArray[1]) * 100 + + (parseInt(versionArray[2]) || 0) + return versionValue +} diff --git a/server/src/utils/mixerConnections/AtemConnection.ts b/server/src/utils/mixerConnections/AtemConnection.ts new file mode 100644 index 00000000..88231df2 --- /dev/null +++ b/server/src/utils/mixerConnections/AtemConnection.ts @@ -0,0 +1,421 @@ +import { Atem, AtemState } from 'atem-connection' + +import { store, state } from '../../reducers/store' +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { logger } from '../logger' +import { storeSetMixerOnline } from '../../../../shared/src/actions/settingsActions' +import { IFader } from '../../../../shared/src/reducers/fadersReducer' +import { IChannel } from '../../../../shared/src/reducers/channelsReducer' +import { dbToFloat, floatToDB } from './LawoRubyConnection' +import { + FairlightAudioMixOption, + FairlightInputConfiguration, +} from 'atem-connection/dist/enums' +import { + storeFaderLevel, + storeInputGain, + storeSetMute, + storeSetPgm, + storeSetVo, +} from '../../../../shared/src/actions/faderActions' +import { storeSetChLabel } from '../../../../shared/src/actions/channelActions' +import { FairlightAudioSource } from 'atem-connection/dist/state/fairlight' + +enum TrackIndex { + Stereo = '-65280', + Right = '-255', + Left = '-256', +} + +export class AtemMixerConnection { + private _connection: Atem + + private _chNoToSource: Record = {} + private _sourceToChNo: Record = {} + private _sourceTracks: Record = {} + private _firstConnection = true + + constructor( + private mixerProtocol: IMixerProtocol, + public mixerIndex: number + ) { + this._connection = new Atem() + + this._connection.on('connected', () => { + logger.info('Atem connected') + store.dispatch(storeSetMixerOnline(this.mixerIndex, true)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex) + + this.setupMixerConnection() + }) + this._connection.on('disconnected', () => { + logger.info('Atem disconnected') + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex) + }) + + this._connection + .connect(state.settings[0].mixers[this.mixerIndex].deviceIp) + .catch((error) => { + logger + .data(error) + .error( + 'Failed to connect to atem ' + + state.settings[0].mixers[this.mixerIndex].deviceIp + ) + }) + } + + setupMixerConnection() { + const sourceToName: Record = { + ...Object.fromEntries( + Object.entries(this._connection.state.inputs).map( + ([id, input]) => [id, input.shortName] + ) + ), + '1301': 'Mic 1', + '1302': 'Mic 2', + } + Object.keys(this._connection.state.fairlight.inputs).forEach( + (source, index) => { + this._chNoToSource[index] = Number(source) + this._sourceToChNo[Number(source)] = index + + this._sourceTracks[index] = TrackIndex.Stereo + + let name = sourceToName[source] + this.setChannelLabel(this._sourceToChNo[Number(source)], name) + } + ) + + if (!this._firstConnection) return + this._firstConnection = false + + const stateChangedHandler = (state: AtemState, changes: string[]) => { + for (const changePath of changes) { + if (!changePath.startsWith('fairlight.inputs')) continue + + const input = parseInt(changePath.split('.')[2]) + const channelIndex = this._sourceToChNo[input] + + if ( + channelIndex === undefined || + !state.fairlight.inputs[input].sources[ + this._sourceTracks[channelIndex] + ] + ) { + continue + } + + const channel = this.getChannel(channelIndex) + const fader = this.getFaderFromChannelIndex(channelIndex) + const source = + state.fairlight.inputs[input].sources[ + this._sourceTracks[channelIndex] + ] + + this.setPropsFromChannel(channelIndex, channel, fader, source) + } + } + this._connection.on('stateChanged', stateChangedHandler) + + return + } + + updateInputGain(channelIndex: number, level: number): void { + const { channelTypeIndex } = this.getChannel(channelIndex) + + this._connection.setFairlightAudioMixerSourceProps( + this._chNoToSource[channelTypeIndex], + this._sourceTracks[channelTypeIndex], + { gain: -1200 + 1800 * level } + ) + } + + updatePflState(channelIndex: number): void { + // todo - add fairlight pfl + return + } + + updateMuteState(channelIndex: number, muteOn: boolean): void { + const { channelTypeIndex, outputLevel } = this.getChannel(channelIndex) + + if (outputLevel > 0) { + this._connection.setFairlightAudioMixerSourceProps( + this._sourceToChNo[channelTypeIndex], + this._sourceTracks[channelTypeIndex], + { + mixOption: muteOn + ? FairlightAudioMixOption.Off + : FairlightAudioMixOption.On, + } + ) + } + } + + updateAMixState(channelIndex: number, amixOn: boolean): void { + return + } + + updateNextAux(channelIndex: number, level: number): void { + return + } + + updateFx(fxParam: fxParamsList, channelIndex: number, level: number): void { + return + } + + updateAuxLevel( + channelIndex: number, + auxSendIndex: number, + auxLevel: number + ): void { + return + } + + updateChannelName(channelIndex: number): void { + return + } + + injectCommand(command: string[]): void { + return + } + + updateChannelSetting( + channelIndex: number, + setting: string, + value: string + ): void { + return + } + + updateInputSelector(channelIndex: number, inputSelected: number) { + const { channelTypeIndex } = this.getChannel(channelIndex) + const { pgmOn, pflOn } = this.getFaderFromChannelIndex(channelIndex) + const tracks = + this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_INPUT_SELECTOR?.[ + inputSelected - 1 + ] + if (!tracks) return + + switch (tracks.label) { + case 'LR': + this._connection.setFairlightAudioMixerInputProps( + this._chNoToSource[channelIndex], + { activeConfiguration: FairlightInputConfiguration.Stereo } + ) + if (pgmOn || pflOn) { + this._connection.setFairlightAudioMixerSourceProps( + this._chNoToSource[channelIndex], + TrackIndex.Stereo, + { + mixOption: FairlightAudioMixOption.On, + } + ) + } + this._sourceTracks[channelTypeIndex] = TrackIndex.Stereo + break + case 'LL': + this._connection.setFairlightAudioMixerInputProps( + this._chNoToSource[channelIndex], + { + activeConfiguration: + FairlightInputConfiguration.DualMono, + } + ) + this._connection.setFairlightAudioMixerSourceProps( + this._chNoToSource[channelIndex], + TrackIndex.Right, + { + mixOption: FairlightAudioMixOption.Off, + } + ) + if (pgmOn || pflOn) { + this._connection.setFairlightAudioMixerSourceProps( + this._chNoToSource[channelIndex], + TrackIndex.Left, + { + mixOption: FairlightAudioMixOption.On, + } + ) + } + this._sourceTracks[channelTypeIndex] = TrackIndex.Left + break + case 'RR': + this._connection.setFairlightAudioMixerInputProps( + this._chNoToSource[channelIndex], + { + activeConfiguration: + FairlightInputConfiguration.DualMono, + } + ) + this._connection.setFairlightAudioMixerSourceProps( + this._chNoToSource[channelIndex], + TrackIndex.Left, + { + mixOption: FairlightAudioMixOption.Off, + } + ) + if (pgmOn || pflOn) { + this._connection.setFairlightAudioMixerSourceProps( + this._chNoToSource[channelIndex], + TrackIndex.Right, + { + mixOption: FairlightAudioMixOption.On, + } + ) + } + + this._sourceTracks[channelTypeIndex] = TrackIndex.Right + break + } + } + + updateFadeIOLevel(channelIndex: number, level: number): void { + const channel = this.getChannel(channelIndex) + const fader = this.getFaderFromChannelIndex(channelIndex) + const { muteOn } = this.getFaderFromChannelIndex(channelIndex) + const sourceNo = this._chNoToSource[channel.channelTypeIndex] + + if (level > 0 && !muteOn) { + this._connection.setFairlightAudioMixerSourceProps( + sourceNo, + this._sourceTracks[channel.channelTypeIndex], + { mixOption: FairlightAudioMixOption.On } + ) + this._connection.setFairlightAudioMixerSourceProps( + sourceNo, + this._sourceTracks[channel.channelTypeIndex], + { + faderGain: Math.round( + Math.max(-10000, Math.min(1000, floatToDB(level) * 100)) + ), + } + ) + } else { + this._connection.setFairlightAudioMixerSourceProps( + sourceNo, + this._sourceTracks[channel.channelTypeIndex], + { mixOption: FairlightAudioMixOption.Off } + ) + this._connection.setFairlightAudioMixerSourceProps( + sourceNo, + this._sourceTracks[channel.channelTypeIndex], + { + faderGain: 0, + } + ) + } + } + + private getFaderFromChannelIndex(channelIndex: number): IFader { + const faderIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].assignedFader + + return state.faders[0].fader[faderIndex] + } + private getChannel(channelIndex: number): IChannel { + return state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + } + + private setPropsFromChannel( + channelIndex: number, + channel: IChannel, + fader: IFader, + source: FairlightAudioSource + ) { + if ((source.properties.gain + 1200) / 1800 !== fader.inputGain) { + // update gain + this.setFaderGain( + channelIndex, + (source.properties.gain + 1200) / 1800 + ) + } + if (!channel.fadeActive) { + if ( + source.properties.mixOption === FairlightAudioMixOption.On && + source.properties.faderGain > -10000 + ) { + if (fader.muteOn) { + // set mute off + this.setMute(channelIndex, false) + } + if (!fader.pgmOn && !fader.voOn) { + // set fader on + this.setFaderPgm(channelIndex, true) + } + } + if ( + source.properties.mixOption === FairlightAudioMixOption.Off && + (fader.pgmOn || fader.voOn) + ) { + // set fader off + this.setFaderPgm(channelIndex, false) + this.setFaderVo(channelIndex, false) + } + if ( + dbToFloat(source.properties.faderGain / 100) !== + fader.faderLevel + ) { + // set fader level + this.setFaderLevel( + channelIndex, + dbToFloat(source.properties.faderGain / 100) + ) + } + } + } + + private setFaderGain( + faderIndex: number, + gain: number, + update: boolean = true + ): void { + store.dispatch(storeInputGain(faderIndex, gain)) + if (update) global.mainThreadHandler.updatePartialStore(faderIndex) + } + private setMute( + faderIndex: number, + muteOn: boolean, + update: boolean = true + ): void { + store.dispatch(storeSetMute(faderIndex, muteOn)) + if (update) global.mainThreadHandler.updatePartialStore(faderIndex) + } + private setFaderPgm( + faderIndex: number, + pgmOn: boolean, + update: boolean = true + ): void { + store.dispatch(storeSetPgm(faderIndex, pgmOn)) + if (update) global.mainThreadHandler.updatePartialStore(faderIndex) + } + private setFaderVo(faderIndex: number, voOn: boolean, update = true): void { + store.dispatch(storeSetVo(faderIndex, voOn)) + if (update) global.mainThreadHandler.updatePartialStore(faderIndex) + } + private setFaderLevel( + faderIndex: number, + level: number, + update: boolean = true + ): void { + store.dispatch(storeFaderLevel(faderIndex, level)) + if (update) global.mainThreadHandler.updatePartialStore(faderIndex) + } + private setChannelLabel( + channelIndex: number, + label: string, + update: boolean = true + ): void { + store.dispatch(storeSetChLabel(this.mixerIndex, channelIndex, label)) + if (update) global.mainThreadHandler.updatePartialStore(channelIndex) + } +} + diff --git a/server/src/utils/mixerConnections/CasparCGConnection.ts b/server/src/utils/mixerConnections/CasparCGConnection.ts new file mode 100644 index 00000000..e70d3a27 --- /dev/null +++ b/server/src/utils/mixerConnections/CasparCGConnection.ts @@ -0,0 +1,588 @@ +//Node Modules: +import osc from 'osc' +import fs from 'fs' +import * as path from 'path' +import { CasparCG } from 'casparcg-connection' + +//Utils: +import { store, state } from '../../reducers/store' +import { + ICasparCGMixerGeometry, + ICasparCGChannelLayerPair, + ICasparCGMixerGeometryFile, + fxParamsList, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { IChannel } from '../../../../shared/src/reducers/channelsReducer' +import { + storeSetChLabel, + storeSetChPrivate, +} from '../../../../shared/src/actions/channelActions' +import { logger } from '../logger' +import { dbToFloat, floatToDB } from './LawoRubyConnection' +import { IFader } from '../../../../shared/src/reducers/fadersReducer' +import { sendVuLevel } from '../vuServer' +import { VuType } from '../../../../shared/src/utils/vu-server-types' +import { storeSetMixerOnline } from '../../../../shared/src/actions/settingsActions' + +interface CommandChannelMap { + [key: string]: number +} + +interface ICasparCGChannel extends IChannel { + producer?: string + source?: string +} + +const OSC_PATH_PRODUCER = + /\/channel\/(\d+)\/stage\/layer\/(\d+)\/producer\/type/ +const OSC_PATH_PRODUCER_FILE_NAME = + /\/channel\/(\d+)\/stage\/layer\/(\d+)\/file\/path/ +const OSC_PATH_PRODUCER_CHANNEL_LAYOUT = + /\/channel\/(\d+)\/stage\/layer\/(\d+)\/producer\/channel_layout/ + +export class CasparCGConnection { + mixerProtocol: ICasparCGMixerGeometry + mixerIndex: number + connection: CasparCG + oscClient: any + oscCommandMap: { [key: string]: CommandChannelMap } = {} + + constructor(mixerProtocol: ICasparCGMixerGeometry, mixerIndex: number) { + this.mixerProtocol = mixerProtocol + this.mixerIndex = mixerIndex + this.injectCasparCGSetting() + + this.connection = new CasparCG({ + autoReconnect: true, + autoReconnectAttempts: 20, + autoReconnectInterval: 3000, + host: state.settings[0].mixers[this.mixerIndex].deviceIp, + port: parseInt( + state.settings[0].mixers[this.mixerIndex].devicePort + '' + ), + }) + logger.info('Trying to connect to CasparCG...') + this.connection.onConnected = () => { + logger.info('CasparCG connected') + store.dispatch(storeSetMixerOnline(this.mixerIndex, true)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex) + + this.setupMixerConnection() + } + this.connection.onDisconnected = () => { + logger.info('CasparCG disconnected') + + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex) + } + this.connection.connect() + + this.oscCommandMap.CHANNEL_VU = {} + this.mixerProtocol.fromMixer.CHANNEL_VU.forEach((paths, index) => { + this.oscCommandMap.CHANNEL_VU[paths[0]] = index + }) + } + + injectCasparCGSetting() { + const geometryFile = path.resolve( + process.cwd(), + 'storage', + 'default-casparcg.ccg' + ) + + let geometry: ICasparCGMixerGeometryFile | undefined + try { + let inputObj = JSON.parse( + fs.readFileSync(geometryFile, { + encoding: 'utf-8', + }) + ) + if (inputObj.toMixer && inputObj.toMixer.PGM_CHANNEL_FADER_LEVEL) { + geometry = inputObj + } + } catch (e) { + // Handling a file should be removed from Constants in the future: + logger.info('CasparCG Audio geometry file has not been created') + } + if (geometry) { + this.mixerProtocol.fromMixer = + geometry.fromMixer || this.mixerProtocol.fromMixer + this.mixerProtocol.toMixer = + geometry.toMixer || this.mixerProtocol.toMixer + this.mixerProtocol.channelLabels = + geometry.channelLabels || this.mixerProtocol.channelLabels + this.mixerProtocol.sourceOptions = + geometry.sourceOptions || this.mixerProtocol.sourceOptions + } + } + + setupMixerConnection() { + const calcVuLevel = (level: number) => { + return dbToFloat(20 * Math.log(level) + 12) + } + if (!this.oscClient) { + const remotePort = + parseInt( + state.settings[0].mixers[this.mixerIndex].devicePort + '' + ) + 1000 + this.oscClient = new osc.UDPPort({ + localAddress: state.settings[0].mixers[this.mixerIndex].localIp, + localPort: remotePort, + remoteAddress: + state.settings[0].mixers[this.mixerIndex].deviceIp, + remotePort, + }) + .on('ready', () => { + logger.info('Receiving state of mixer') + }) + .on('message', (message: any) => { + for (const channelIndex in this.mixerProtocol.fromMixer + .CHANNEL_VU) { + for (const vuChannelIndex in this.mixerProtocol + .fromMixer.CHANNEL_VU[channelIndex]) { + if ( + message.address === + this.mixerProtocol.fromMixer.CHANNEL_VU[ + channelIndex + ][vuChannelIndex] + ) { + const faderIndex = + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel[channelIndex].assignedFader + sendVuLevel( + faderIndex, + VuType.Channel, + parseInt(vuChannelIndex), + calcVuLevel(message.args[0]) + ) + } + } + } + if (this.mixerProtocol.sourceOptions) { + const m = message.address.split('/') + + if ( + m[1] === 'channel' && + m[6] === 'producer' && + m[7] === 'type' + ) { + const index = + this.mixerProtocol.sourceOptions.sources.findIndex( + (i) => + i.channel === parseInt(m[2], 10) && + i.layer === parseInt(m[5]) + ) + if (index >= 0) { + store.dispatch( + storeSetChPrivate( + index, + 'producer', + message.args[0] + ) + ) + } + } else if ( + m[1] === 'channel' && + m[6] === 'producer' && + m[7] === 'channel_layout' + ) { + const index = + this.mixerProtocol.sourceOptions.sources.findIndex( + (i) => + i.channel === parseInt(m[2], 10) && + i.layer === parseInt(m[5]) + ) + if (index >= 0) { + store.dispatch( + storeSetChPrivate( + index, + 'channel_layout', + message.args[0] + ) + ) + } + } else if ( + m[1] === 'channel' && + m[6] === 'file' && + m[7] === 'path' + ) { + const index = + this.mixerProtocol.sourceOptions.sources.findIndex( + (i) => + i.channel === parseInt(m[2], 10) && + i.layer === parseInt(m[5]) + ) + if (index >= 0) { + const value = + typeof message.args[0] === 'string' + ? message.args[0] + : message.args[0].low + store.dispatch( + storeSetChPrivate(index, 'file_path', value) + ) + } + } + } + }) + .on('error', (error: any) => { + logger.data(error).error('Lost OSC connection') + }) + + this.oscClient.open() + const remoteIp = state.settings[0].mixers[this.mixerIndex].deviceIp + logger.info( + `Listening for status on CasparCG: ${remoteIp}:${remotePort}` + ) + } + + // Restore mixer values to the ones we have internally + state.channels[0].chMixerConnection[this.mixerIndex].channel.forEach( + (channel: IChannel, index) => { + // const fader = state.faders[0].fader[channel.assignedFader] + this.updateFadeIOLevel(index, channel.outputLevel) + this.updatePflState(index) + } + ) + + // Set source labels from geometry definition + if (this.mixerProtocol.channelLabels) { + this.mixerProtocol.channelLabels.forEach((label, channelIndex) => { + store.dispatch( + storeSetChLabel(this.mixerIndex, channelIndex, label) + ) + }) + } + } + + checkOscCommand( + address: string, + commandSpace: CommandChannelMap + ): number | undefined { + const index = commandSpace[address] + if (index !== undefined) { + return index + } + return undefined + } + + pingMixerCommand = () => { + //Ping OSC mixer if mixerProtocol needs it. + /* this.mixerProtocol.pingCommand.map((command) => { + this.sendOutMessage( + command.mixerMessage, + 0, + command.value + ); + }); */ + } + + private syncCommand = Promise.resolve() + floatToVolume = (float: number) => { + const db = floatToDB(float) + const volume = Math.pow(10, db / 20) + + return Math.min(Math.max(volume, 0), 3.2) // clamp between 0 and 3.2 + } + controlVolume = (channel: number, layer: number, value: number) => { + logger.trace(`Set ${channel}-${layer} volume = ${value}`) + this.syncCommand = this.syncCommand + .then(() => + this.connection + .mixerVolume( + channel, + layer, + this.floatToVolume(value), + 0, + undefined + ) + .catch((e: any) => { + logger.data(e).error('Failed to send command') + }) + ) + .then(() => {}) + } + + controlChannelSetting = ( + channel: number, + layer: number, + producer: string, + file: string, + setting: string, + value: string + ) => { + this.connection + .stop(channel, layer) + .then(() => { + if (setting === 'CHANNEL_LAYOUT') { + switch (producer) { + case 'ffmpeg': + return this.connection.play( + channel, + layer, + file, + true, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + value + ) + case 'decklink': + return this.connection.playDecklink( + channel, + layer, + parseInt(file, 10), + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + value + ) + case 'layer-producer': + return this.connection.playRoute( + channel, + layer, + file, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + value, + undefined + ) + } + } + return Promise.reject('Unknown operation') + }) + .then(() => {}) + .catch((e: any) => { + logger.data(e).error('Failed to change channel setting') + }) + } + + setAllLayers = (pairs: ICasparCGChannelLayerPair[], value: number) => { + pairs.forEach((i) => { + this.controlVolume(i.channel, i.layer, value) + }) + } + + updatePflState(channelIndex: number) { + if ( + channelIndex > + this.mixerProtocol.toMixer.PGM_CHANNEL_FADER_LEVEL.length - 1 + ) { + return + } + logger.trace(`Update PFL state for ${channelIndex}`) + const channel: IChannel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + const fader: IFader = state.faders[0].fader[channel.assignedFader] + const otherFaders: Array = state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel + .filter((_ch: any, i: number) => i !== channelIndex) + .map((ch: IChannel) => state.faders[0].fader[ch.assignedFader]) + if (fader.pflOn === true) { + // Enable SOLO on this channel on MONITOR + const pairs = + this.mixerProtocol.toMixer.PFL_AUX_FADER_LEVEL[channelIndex] + this.setAllLayers( + pairs, + state.faders[0].fader[channel.assignedFader].faderLevel + ) + // Ensure that all other non-SOLO channels are muted on MONITOR + // const others = state.channels[0].chMixerConnection[this.mixerIndex].channel.map((ch: IChannel) => state.faders[0].fader[ch.assignedFader].pflOn ? undefined : index) + const others = state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel + .map((ch: IChannel, index: number) => + state.faders[0].fader[ch.assignedFader].pflOn + ? undefined + : index + ) + .filter( + (i) => + i !== undefined && + i < + this.mixerProtocol.toMixer.PFL_AUX_FADER_LEVEL + .length + ) as number[] + others.forEach((i) => { + const pairs = this.mixerProtocol.toMixer.PFL_AUX_FADER_LEVEL[i] + this.setAllLayers(pairs, this.mixerProtocol.fader.min) + }) + } else { + // check if any other channels are SOLO + const others = otherFaders + .map((i, index) => (i.pflOn ? index : undefined)) + .filter( + (i) => + i !== undefined && + i < + this.mixerProtocol.toMixer.PFL_AUX_FADER_LEVEL + .length + ) as number[] + if (others.length > 0) { + // other channels are SOLO, mute this channel on PFL + const pairs = + this.mixerProtocol.toMixer.PFL_AUX_FADER_LEVEL[channelIndex] + this.setAllLayers(pairs, this.mixerProtocol.fader.min) + } else { + // There are no other SOLO channels, restore PFL to match PGM + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((_ch: IChannel, index: number) => { + if ( + index > + this.mixerProtocol.toMixer.PFL_AUX_FADER_LEVEL.length - + 1 + ) { + return + } + const pairs = + this.mixerProtocol.toMixer.PFL_AUX_FADER_LEVEL[index] + this.setAllLayers( + pairs, + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[index].outputLevel + ) + }) + } + } + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + return true + } + + updateNextAux(channelIndex: number, level: number) { + if ( + channelIndex > + this.mixerProtocol.toMixer.PGM_CHANNEL_FADER_LEVEL.length - 1 + ) { + return + } + logger.trace(`Update NEXT AUX for ${channelIndex}`) + if (this.mixerProtocol.toMixer.NEXT_AUX_FADER_LEVEL) { + const faderIndex: number = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].assignedFader + if (state.faders[0].fader[faderIndex].pstOn === true) { + // add this channel to the PST mix + const pairs = + this.mixerProtocol.toMixer.NEXT_AUX_FADER_LEVEL[faderIndex] + this.setAllLayers( + pairs, + state.faders[0].fader[faderIndex].faderLevel + ) + } else { + // mute this channel to the PST mix + const pairs = + this.mixerProtocol.toMixer.NEXT_AUX_FADER_LEVEL[faderIndex] + this.setAllLayers(pairs, this.mixerProtocol.fader.min) + } + } + } + + updateInputGain(channelIndex: number, level: number) { + return true + } + updateInputSelector(channelIndex: number, inputSelected: number) { + if ( + this.mixerProtocol.toMixer.CHANNEL_INPUT_SELECTOR && + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].private + ) { + const pair = this.mixerProtocol.sourceOptions.sources[channelIndex] + const producer = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].private!['producer'] + let filePath = String( + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].private!['file_path'] + ) + filePath = filePath.replace(/\.[\w\d]+$/, '') + this.controlChannelSetting( + pair.channel, + pair.layer, + producer, + filePath, + 'CHANNEL_LAYOUT', + this.mixerProtocol.toMixer.CHANNEL_INPUT_SELECTOR[ + inputSelected - 1 + ].mixerMessage + ) + } + } + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + return true + } + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + return true + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + if ( + channelIndex > + this.mixerProtocol.toMixer.PGM_CHANNEL_FADER_LEVEL.length - 1 + ) { + return + } + + logger.trace( + `updateFadeIOLevel: channelId: ${channelIndex}, fader.pflOn = "${state.faders[0].fader[channelIndex].pflOn}". faderLevel = "${state.faders[0].fader[channelIndex].faderLevel}"` + ) + + const faderIndex: number = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].assignedFader + const pgmPairs = + this.mixerProtocol.toMixer.PGM_CHANNEL_FADER_LEVEL[channelIndex] + this.setAllLayers(pgmPairs, outputLevel) + + const anyPflOn = state.faders[0].fader.find((f: IFader) => f.pflOn) + // Check if there are no SOLO channels on MONITOR or there are, but this channel is SOLO + if (!anyPflOn || state.faders[0].fader[faderIndex].pflOn) { + const pairs = + this.mixerProtocol.toMixer.PFL_AUX_FADER_LEVEL[channelIndex] + if (state.faders[0].fader[faderIndex].pflOn) { + this.setAllLayers( + pairs, + state.faders[0].fader[faderIndex].faderLevel + ) + } else { + this.setAllLayers(pairs, outputLevel) + } + } + } + + updateChannelName(channelIndex: number) { + //CasparCG does not need Labels. + } + + loadMixerPreset(presetName: string) { + // This is where CasparCG settings preset loading should be refactored to + } + + injectCommand(command: string[]) { + this.connection.createCommand(command[0]) + } +} diff --git a/server/src/utils/mixerConnections/EmberMixerConnection.ts b/server/src/utils/mixerConnections/EmberMixerConnection.ts new file mode 100644 index 00000000..f87a3733 --- /dev/null +++ b/server/src/utils/mixerConnections/EmberMixerConnection.ts @@ -0,0 +1,958 @@ +import { EmberClient, Model, Types } from 'emberplus-connection' +import { store, state } from '../../reducers/store' +import { remoteConnections } from '../../mainClasses' +import path from 'path' +import fs from 'fs' + +//Utils: +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { + storeFaderLevel, + storeInputGain, + storeSetPgm, + storeSetPfl, + storeShowChannel, + storeSetAMix, + storeCapability, + storeInputSelector, +} from '../../../../shared/src/actions/faderActions' +import { logger } from '../logger' +import { LawoMC2 } from '../../../../shared/src/constants/mixerProtocols/LawoMC2' +import { dbToFloat, floatToDB } from './LawoRubyConnection' +import { + SET_OUTPUT_LEVEL, + storeSetChLabel, +} from '../../../../shared/src/actions/channelActions' +import { storeSetMixerOnline } from '../../../../shared/src/actions/settingsActions' + +export class EmberMixerConnection { + mixerProtocol: IMixerProtocol + mixerIndex: number + emberConnection: EmberClient + deviceRoot: any + emberNodeObject: Array + isSubscribedToChannel: Array = [] + + constructor(mixerProtocol: IMixerProtocol, mixerIndex: number) { + this.sendOutMessage = this.sendOutMessage.bind(this) + this.pingMixerCommand = this.pingMixerCommand.bind(this) + + this.emberNodeObject = new Array(200) + this.mixerProtocol = mixerProtocol + this.mixerIndex = mixerIndex + + this.setupEmberSocket() + } + + setupEmberSocket() { + logger.info('Setting up new Ember connection') + this.emberConnection = new EmberClient( + state.settings[0].mixers[this.mixerIndex].deviceIp, + state.settings[0].mixers[this.mixerIndex].devicePort + ) + + this.emberConnection.on('error', (error: any) => { + if ( + (error.message + '').match(/econnrefused/i) || + (error.message + '').match(/disconnected/i) + ) { + logger.error('Ember connection not establised') + } else { + logger.data(error).error('Ember connection unknown error') + } + }) + this.emberConnection.on('disconnected', () => { + logger.error('Lost Ember connection') + + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex) + + this.emberNodeObject = [] + this.isSubscribedToChannel = [] + this.emberConnection.tree = [] + // this.emberConnection.discard() + // delete this.emberConnection + // this.setupEmberSocket() + }) + this.emberConnection.on('connected', async () => { + logger.info('Found Ember connection') + + store.dispatch(storeSetMixerOnline(this.mixerIndex, true)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex) + + const req = await this.emberConnection.getDirectory( + this.emberConnection.tree + ) + + await req.response + + this.setupMixerConnection() + }) + logger.info('Connecting to Ember') + this.emberConnection.connect() + } + + async setupMixerConnection() { + logger.info( + 'Ember connection established - setting up subscription of channels' + ) + + let ch: number = 1 + for (const [typeIndex, numberOfChannels] of Object.entries( + state.settings[0].mixers[this.mixerIndex].numberOfChannelsInType + )) { + for ( + let channelTypeIndex = 0; + channelTypeIndex < numberOfChannels; + channelTypeIndex++ + ) { + if (this.mixerProtocol.label === LawoMC2.label) { + await this.subscribeToMc2ChannelOnline( + ch, + Number(typeIndex), + channelTypeIndex + ) + } else { + await this.setupFaderSubscriptions( + ch, + Number(typeIndex), + channelTypeIndex + ) + } + + ch++ + } + } + } + + async setupFaderSubscriptions( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const protocol = + this.mixerProtocol.channelTypes[Number(typeIndex)].fromMixer + + await this.subscribeFaderLevel(ch, Number(typeIndex), channelTypeIndex) + + if (protocol.CHANNEL_NAME) + await this.subscribeChannelName( + ch, + Number(typeIndex), + channelTypeIndex + ) + + if (protocol.PFL) + await this.subscribeChannelPFL( + ch, + Number(typeIndex), + channelTypeIndex + ) + + if (protocol.CHANNEL_AMIX) + await this.subscribeAMix(ch, Number(typeIndex), channelTypeIndex) + + if (protocol.CHANNEL_INPUT_GAIN) + await this.subscribeChannelInputGain( + ch, + Number(typeIndex), + channelTypeIndex + ) + + if (protocol.CHANNEL_INPUT_SELECTOR) { + if (this.mixerProtocol.label === LawoMC2.label) { + await this.subscribeToMc2InputSelector( + ch, + Number(typeIndex), + channelTypeIndex + ) + } else { + await this.subscribeChannelInputSelector( + ch, + Number(typeIndex), + channelTypeIndex + ) + } + } + } + + async subscribeToMc2ChannelOnline( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const mixerMessage = 'Channels.Inputs.${channel}.Fader' + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ch - 1] + + await this.subscribeToEmberNode( + channelTypeIndex, + mixerMessage, + async (node: Model.NumberedTreeNode) => { + if (node.contents.isOnline) { + logger.info(`Channel ${ch} online`) + if (!this.isSubscribedToChannel[ch - 1]) { + this.isSubscribedToChannel[ch - 1] = true + await this.setupFaderSubscriptions( + ch, + typeIndex, + channelTypeIndex + ) + } + store.dispatch( + storeShowChannel(channel.assignedFader, true) + ) + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + } else { + logger.info(`Channel ${ch} offline`) + store.dispatch( + storeShowChannel(channel.assignedFader, false) + ) + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + } + } + ) + } + + async subscribeToEmberNode( + channelTypeIndex: number, + mixerMessage: string, + cb: (node: Model.TreeElement) => void + ) { + const channelName = this._insertChannelName( + mixerMessage, + String(channelTypeIndex + 1) + ) + logger.trace(`Subscribe to ${channelName}`) + try { + const node = await this.emberConnection.getElementByPath( + this._insertChannelName( + mixerMessage, + String(channelTypeIndex + 1) + ) + ) + if (!node) return + + await this.emberConnection.subscribe(node, cb) + + cb(node) + } catch (e) { + logger.data(e).debug('Error when subscribing to fader label') + } + } + + async subscribeFaderLevel( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + let mixerMessage = this._insertChannelName( + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_OUT_GAIN[0].mixerMessage, + String(channelTypeIndex + 1) + ) + + await this.subscribeToEmberNode( + channelTypeIndex, + mixerMessage, + (node) => { + const parameter = node.contents as Model.Parameter + const val = (parameter.value as number) / parameter.factor + const level = this._faderLevelToFloat(val, typeIndex) + const channel = + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1] + + logger.trace( + `Receiving Level from Ch "${ch}", val: ${val}, level: ${level}` + ) + + if (!channel.fadeActive && level >= 0 && level <= 1) { + store.dispatch( + storeFaderLevel(channel.assignedFader, level) + ) + store.dispatch({ + type: SET_OUTPUT_LEVEL, + channel: channel.assignedFader, + mixerIndex: this.mixerIndex, + level, + }) + + // toggle pgm based on level + logger.trace(`Set Channel ${ch} pgmOn ${level > 0}`) + store.dispatch( + storeSetPgm(channel.assignedFader, level > 0) + ) + + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + channel.assignedFader, + level + ) + } + } + } + ) + this.emberNodeObject[ch - 1] = + await this.emberConnection.getElementByPath(mixerMessage) + } + + async subscribeChannelName( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const mixerMessage = + this.mixerProtocol.channelTypes[typeIndex].fromMixer.CHANNEL_NAME[0] + .mixerMessage + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ch - 1] + await this.subscribeToEmberNode( + channelTypeIndex, + mixerMessage, + (node) => { + if (node.contents.type === Model.ElementType.Node) { + logger.trace( + `Receiving Label from Ch "${ch}", val: ${node.contents.description}` + ) + store.dispatch( + storeSetChLabel( + this.mixerIndex, + channelTypeIndex, + node.contents.description + ) + ) + } else { + logger.trace( + `Receiving Label from Ch "${ch}", val: ${ + (node.contents as Model.Parameter).value + }` + ) + store.dispatch( + storeSetChLabel( + this.mixerIndex, + channelTypeIndex, + String((node.contents as Model.Parameter).value) + ) + ) + } + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + } + ) + } + + async subscribeChannelPFL( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const mixerMessage = + this.mixerProtocol.channelTypes[typeIndex].fromMixer.PFL[0] + .mixerMessage + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ch - 1] + + await this.subscribeToEmberNode( + channelTypeIndex, + mixerMessage, + (node) => { + logger.trace( + `Receiving PFL from Ch "${ch}", val: ${ + (node.contents as Model.Parameter).value + }` + ) + store.dispatch( + storeSetPfl( + channel.assignedFader, + (node.contents as Model.Parameter).value as boolean + ) + ) + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + } + ) + } + + async subscribeChannelInputGain( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const mixerMessage = + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_INPUT_GAIN[0].mixerMessage + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ch - 1] + + await this.subscribeToEmberNode( + channelTypeIndex, + mixerMessage, + (node) => { + logger.trace( + `Receiving input gain from Ch "${ch}", val: ${ + (node.contents as Model.Parameter).value + }` + ) + + let level = (node.contents as Model.Parameter).value + if ( + (node.contents as Model.Parameter).factor && + typeof level === 'number' + ) { + level /= (node.contents as Model.Parameter).factor + } + + // assume it is in db now + level = this._faderLevelToFloat(Number(level), 0) + store.dispatch(storeInputGain(channel.assignedFader, level)) + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + } + ) + } + + async subscribeChannelInputSelector( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ch - 1] + for (const i in this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_INPUT_SELECTOR) { + const proto = + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_INPUT_SELECTOR[i] + const mixerMessage = proto.mixerMessage + + await this.subscribeToEmberNode( + channelTypeIndex, + mixerMessage, + (node) => { + logger.trace( + `Receiving input selector from Ch "${ch}", val: ${i}: ${ + (node.contents as Model.Parameter).value + }` + ) + + let value = (node.contents as Model.Parameter).value + + if (value === proto.value) { + logger.trace( + `Dispatching input selector Ch "${ch}", selected: ${ + i + 1 + }` + ) + store.dispatch( + storeInputSelector( + channel.assignedFader, + Number(i) + 1 + ) + ) + } + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + } + ) + } + } + + async subscribeToMc2InputSelector( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + // subscription for enabling input selectors + const mixerMessage = 'Channels.Inputs.${channel}.Channel States.Stereo' + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ch - 1] + await this.subscribeToEmberNode( + channelTypeIndex, + mixerMessage, + (node) => { + logger.trace( + `Update received for ch inp sel capability: ${ + (node.contents as Model.Parameter).value + }` + ) + store.dispatch( + storeCapability( + channel.assignedFader, + 'hasInputSelector', + (node.contents as Model.Parameter).value as boolean + ) + ) + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + } + ) + // subscribe to input selectors + let llState = false + let rrState = false + + const updateState = () => { + if (llState && !rrState) { + logger.trace(`Input selector state: ll`) + store.dispatch(storeInputSelector(channel.assignedFader, 2)) + } else if (rrState && !llState) { + logger.trace(`Input selector state: rr`) + store.dispatch(storeInputSelector(channel.assignedFader, 3)) + } else { + logger.trace(`Input selector state: lr`) + store.dispatch(storeInputSelector(channel.assignedFader, 1)) + } + global.mainThreadHandler.updatePartialStore(channel.assignedFader) + } + + const llMixerMessage = + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_INPUT_SELECTOR[1].mixerMessage + const rrMixerMessage = + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_INPUT_SELECTOR[2].mixerMessage + + await this.subscribeToEmberNode( + channelTypeIndex, + llMixerMessage, + (node) => { + logger.trace( + `Update received for ch inp sel: ll: ${ + (node.contents as Model.Parameter).value + }` + ) + llState = (node.contents as Model.Parameter).value as boolean + updateState() + } + ) + await this.subscribeToEmberNode( + channelTypeIndex, + rrMixerMessage, + (node) => { + logger.trace( + `Update received for ch inp sel: rr: ${ + (node.contents as Model.Parameter).value + }` + ) + rrState = (node.contents as Model.Parameter).value as boolean + updateState() + } + ) + } + + async subscribeAMix( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ch - 1] + if (this.mixerProtocol.label === LawoMC2.label) { + // subscription for enabling amix button + const mixerMessage = + 'Channels.Inputs.${channel}.Automix.Automix Group Assignment' + await this.subscribeToEmberNode( + channelTypeIndex, + mixerMessage, + (node) => { + logger.trace( + `Update received for amix capability: ${ + (node.contents as Model.Parameter).value + }` + ) + store.dispatch( + storeCapability( + channel.assignedFader, + 'hasAMix', + (node.contents as Model.Parameter).value !== + ((node.contents as Model.Parameter).maximum || + 63) // max is unassigned, max = 63 in firmware 6.4 + ) + ) + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + } + ) + } + // subscribe to amix + const mixerMessage = + this.mixerProtocol.channelTypes[typeIndex].fromMixer.CHANNEL_AMIX[0] + .mixerMessage + await this.subscribeToEmberNode( + channelTypeIndex, + mixerMessage, + (node) => { + logger.trace( + `Receiving AMix from Ch "${ch}", val: ${ + (node.contents as Model.Parameter).value + }` + ) + store.dispatch( + storeSetAMix( + channel.assignedFader, + (node.contents as Model.Parameter).value as boolean + ) + ) + global.mainThreadHandler.updatePartialStore( + channel.assignedFader + ) + } + ) + } + + pingMixerCommand() { + //Ping Ember mixer if mixerProtocol needs it. + return + this.mixerProtocol.pingCommand.map((command) => { + this.sendOutMessage( + command.mixerMessage, + 0, + command.value, + command.type + ) + }) + } + + sendOutMessage( + mixerMessage: string, + channel: number, + value: string | number | boolean, + type: string + ) { + let message = this._insertChannelName(mixerMessage, channel.toString()) + logger.trace('Sending out message : ' + message + ', val: ' + value) + + this.emberConnection + .getElementByPath(message) + .then((element: any) => { + if (element.contents.factor && typeof value === 'number') { + value *= element.contents.factor + } + logger.trace( + `Sending out message: ${message}\n val: ${value}\n typeof: ${typeof value}` + ) + this.emberConnection.setValue(element, value) + }) + .catch((error: any) => { + logger.data(error).error('Ember Error') + }) + } + + sendOutLevelMessage(channel: number, value: number) { + logger.trace(`Sending out Level: ${value}\n To CH: ${channel}`) + const node = this.emberNodeObject[channel - 1] + if (!node) return + if (node.contents.factor) { + value *= node.contents.factor + } + this.emberConnection + .setValue(this.emberNodeObject[channel - 1], value, false) + .catch((error: any) => { + logger.data(error).error('Ember Error') + }) + } + + sendOutRequest(mixerMessage: string, channel: number) { + let channelString = this.mixerProtocol.leadingZeros + ? ('0' + channel).slice(-2) + : channel.toString() + // let message = mixerMessage.replace('{channel}', channelString) + let message = this._insertChannelName(mixerMessage, channelString) + if (message != 'none') { + /* + this.oscConnection.send({ + address: message + }); +*/ + } + } + + updateOutLevel(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let protocol = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0] + let level = + (state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].outputLevel - + protocol.min) * + (protocol.max - protocol.min) + this.sendOutLevelMessage(channelTypeIndex + 1, level) + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + // let protocol = this.mixerProtocol.channelTypes[channelType].toMixer + // .CHANNEL_OUT_GAIN[0] + // let level = (outputLevel - protocol.min) * (protocol.max - protocol.min) + + const level = this._floatToFaderLevel(outputLevel, channelTypeIndex) + + this.sendOutLevelMessage(channelTypeIndex + 1, level) + } + + updatePflState(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + + if (state.faders[0].fader[channelIndex].pflOn === true) { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .mixerMessage, + channelTypeIndex + 1, + !!this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .value as any, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .type + ) + } else { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .mixerMessage, + channelTypeIndex + 1, + !!this.mixerProtocol.channelTypes[channelType].toMixer + .PFL_OFF[0].value as any, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .type + ) + } + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + return true + } + + updateNextAux(channelIndex: number, level: number) { + return true + } + + updateInputGain(channelIndex: number, gain: number) { + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + let channelType = channel.channelType + let channelTypeIndex = channel.channelTypeIndex + let protocol = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_INPUT_GAIN[0] + + let level = this._floatToFaderLevel(gain, 0) + + // let level = gain * (protocol.max - protocol.min) + protocol.min + + this.sendOutMessage( + protocol.mixerMessage, + channelTypeIndex + 1, + level, + '' + ) + } + updateInputSelector(channelIndex: number, inputSelected: number) { + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + let channelType = channel.channelType + let channelTypeIndex = channel.channelTypeIndex + + logger.debug(`select in ${channelIndex} ${inputSelected}`) + + if (this.mixerProtocol.label === LawoMC2.label) { + if (inputSelected === 1) { + // LR + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_SELECTOR[1].mixerMessage, + channelTypeIndex + 1, + false as any, + 'boolean' + ) + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_SELECTOR[2].mixerMessage, + channelTypeIndex + 1, + false as any, + 'boolean' + ) + } else if (inputSelected === 2) { + // LL + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_SELECTOR[1].mixerMessage, + channelTypeIndex + 1, + true as any, + 'boolean' + ) + } else if (inputSelected === 3) { + // RR + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer + .CHANNEL_INPUT_SELECTOR[2].mixerMessage, + channelTypeIndex + 1, + true as any, + 'boolean' + ) + } + } + + return true + } + + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + return true + } + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + return true + } + + updateChannelName(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let channelName = state.faders[0].fader[channelIndex].label + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_NAME[0] + .mixerMessage, + channelTypeIndex + 1, + channelName, + 'string' + ) + } + + updateAMixState(channelIndex: number, amixOn: boolean) { + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + let channelType = channel.channelType + let channelTypeIndex = channel.channelTypeIndex + let protocol = + this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_AMIX[0] + + this.sendOutMessage( + protocol.mixerMessage, + channelTypeIndex + 1, + amixOn, + '' + ) + } + + async loadMixerPreset(presetName: string) { + logger.info(`Loading preset: ${presetName}`) + if (this.mixerProtocol.presetFileExtension === 'MC2') { + let data = JSON.parse( + fs + .readFileSync( + path.resolve(process.cwd(), 'storage', presetName) + ) + .toString() + ) + + const loadFunction = await this.emberConnection.getElementByPath( + this.mixerProtocol.loadPresetCommand[0].mixerMessage + ) + + if (loadFunction.contents.type === Model.ElementType.Function) { + this.emberConnection.invoke( + loadFunction as any, + data.sceneAddress + ) + } + } + } + + injectCommand(command: string[]) { + return true + } + + private _insertChannelName(command: string, channel: string | number) { + const pad = (inp: string | number, l: number) => + (' ' + inp).substr(-l) + + if (this.mixerProtocol.label === LawoMC2.label) { + const channelName = '_' + Number(channel).toString(16) // 'INP ' + pad(channel, 3) + return command.replace('${channel}', channelName) + } else if (this.mixerProtocol.leadingZeros) { + return command.replace('${channel}', pad(channel, 2)) + } else { + return command.replace('${channel}', channel + '') + } + } + + private _floatToFaderLevel(value: number, typeIndex: number) { + if (this.mixerProtocol.label === LawoMC2.label) { + return floatToDB(value) + } else { + const range = + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_OUT_GAIN[0].max - + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_OUT_GAIN[0].min + const min = + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_OUT_GAIN[0].min + + return value / range + min + } + } + + private _faderLevelToFloat(value: number, typeIndex: number) { + if (this.mixerProtocol.label === LawoMC2.label) { + return dbToFloat(value) + } else { + const range = + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_OUT_GAIN[0].max - + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_OUT_GAIN[0].min + const min = + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_OUT_GAIN[0].min + + return (value - min) / range + } + } +} diff --git a/server/src/utils/mixerConnections/LawoRubyConnection.ts b/server/src/utils/mixerConnections/LawoRubyConnection.ts new file mode 100644 index 00000000..61574a43 --- /dev/null +++ b/server/src/utils/mixerConnections/LawoRubyConnection.ts @@ -0,0 +1,629 @@ +import { EmberClient, Model } from 'emberplus-connection' +import { store, state } from '../../reducers/store' +import { remoteConnections } from '../../mainClasses' + +//Utils: +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { + SET_INPUT_SELECTOR, + storeFaderLevel, + storeInputGain, + storeChannelDisabled, + storeSetAMix, + storeCapability, + storeShowChannel, +} from '../../../../shared/src/actions/faderActions' +import { logger } from '../logger' +import { storeSetMixerOnline } from '../../../../shared/src/actions/settingsActions' +import { storeSetChLabel } from '../../../../shared/src/actions/channelActions' + +// TODO - should these be util functions? +export function floatToDB(f: number): number { + if (f >= 0.5) { + return f * 40 - 30 // max dB value: +10. + } else if (f >= 0.25) { + return f * 80 - 50 + } else if (f >= 0.0625) { + return f * 160 - 70 + } else if (f > 0.0) { + return f * 480 - 90 // min dB value: -90 or -oo + } else { + return -191 + } +} + +export function dbToFloat(d: number): number { + let f: number + if (d < -60) { + f = (d + 90) / 480 + } else if (d < -30) { + f = (d + 70) / 160 + } else if (d < -10) { + f = (d + 50) / 80 + } else if (d <= 10) { + f = (d + 30) / 40 + } else { + f = 1 + } + return Math.max(0, f) +} + +export class LawoRubyMixerConnection { + mixerProtocol: IMixerProtocol + mixerIndex: number + emberConnection: EmberClient + faders: { [index: number]: string } = {} + + constructor(mixerProtocol: IMixerProtocol, mixerIndex: number) { + this.sendOutMessage = this.sendOutMessage.bind(this) + this.pingMixerCommand = this.pingMixerCommand.bind(this) + + this.mixerProtocol = mixerProtocol + this.mixerIndex = mixerIndex + + logger.info('Setting up Ember connection') + this.emberConnection = new EmberClient( + state.settings[0].mixers[this.mixerIndex].deviceIp, + state.settings[0].mixers[this.mixerIndex].devicePort + ) + + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + + this.emberConnection.on('error', (error: any) => { + if ( + (error.message + '').match(/econnrefused/i) || + (error.message + '').match(/disconnected/i) + ) { + logger.error('Ember connection not establised') + } else { + logger.data(error).error('Ember connection unknown error') + } + }) + this.emberConnection.on('disconnected', () => { + logger.error('Lost Ember connection') + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex) + }) + this.emberConnection.on('connected', () => { + logger.info('Connected to Ember device') + store.dispatch(storeSetMixerOnline(this.mixerIndex, true)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex) + }) + + logger.info('Connecting to Ember') + this.emberConnection + .connect() + .then(async () => { + logger.debug('Getting Directory') + const req = await this.emberConnection.getDirectory( + this.emberConnection.tree + ) + const r = await req.response + + logger.data(r).debug('Directory:') + this.setupMixerConnection() + }) + .then(() => {}) + .catch((e: any) => { + logger.debug(e.stack) + }) + } + + async setupMixerConnection() { + logger.info( + 'Ember connection established - setting up subscription of channels' + ) + + // get the node that contains the sources + const sourceNode = await this.emberConnection.getElementByPath( + 'Ruby.Sources' + ) + // get the sources + const req = await this.emberConnection.getDirectory(sourceNode) + const sources = await req.response + + // map sourceNames to their fader number + if ('children' in sources) { + for (const [_i, child] of Object.entries(sources.children)) { + if ( + child.contents.type === Model.ElementType.Node && + child.contents.identifier + ) { + const name = child.contents.identifier + const fader = await this.emberConnection.getElementByPath( + `Ruby.Sources.${name}.Fader.Number` + ) + this.faders[ + (fader.contents as Model.Parameter).value as number + ] = name + } + } + } + + // Set channel labels + state.settings[0].mixers[ + this.mixerIndex + ].numberOfChannelsInType.forEach( + async (numberOfChannels, typeIndex) => { + for ( + let channelTypeIndex = 0; + channelTypeIndex < numberOfChannels; + channelTypeIndex++ + ) { + if (this.faders[channelTypeIndex + 1]) { + // enable + store.dispatch( + storeSetChLabel( + this.mixerIndex, + channelTypeIndex, + this.faders[channelTypeIndex + 1] + ) + ) + store.dispatch( + storeChannelDisabled(channelTypeIndex, false) + ) + store.dispatch(storeShowChannel(channelTypeIndex, true)) + } else { + // disable + store.dispatch( + storeChannelDisabled(channelTypeIndex, true) + ) + store.dispatch( + storeSetChLabel( + this.mixerIndex, + channelTypeIndex, + '' + ) + ) + store.dispatch( + storeShowChannel(channelTypeIndex, false) + ) + } + } + } + ) + + let ch: number = 1 + for (const typeIndex in state.settings[0].mixers[this.mixerIndex] + .numberOfChannelsInType) { + const numberOfChannels = + state.settings[0].mixers[this.mixerIndex] + .numberOfChannelsInType[typeIndex] + for ( + let channelTypeIndex = 0; + channelTypeIndex < numberOfChannels; + channelTypeIndex++ + ) { + logger.debug(`Running subscriptions for ${this.faders[ch]}`) + try { + await this.subscribeFaderLevel( + ch, + Number(typeIndex), + channelTypeIndex + ) + await this.subscribeGainLevel( + ch, + Number(typeIndex), + channelTypeIndex + ) + await this.subscribeInputSelector( + ch, + Number(typeIndex), + channelTypeIndex + ) + await this.subscribeAMixState( + ch, + Number(typeIndex), + channelTypeIndex + ) + ch++ + } catch (e) { + logger + .data(e) + .error( + `error during subscriptions of parameters for ${this.faders[ch]}` + ) + } + } + } + } + + async subscribeFaderLevel( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const sourceName = this.faders[ch] + if (!sourceName) return + + let command = this.mixerProtocol.channelTypes[ + typeIndex + ].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage.replace( + '{channel}', + sourceName + ) + + try { + const node = await this.emberConnection.getElementByPath(command) + if (node.contents.type !== Model.ElementType.Parameter) return + + logger.debug(`Subscription of channel level: ${command}`) + this.emberConnection.subscribe(node, () => { + logger.trace(`Receiving Level from Ch ${ch}`) + if ( + !state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].fadeActive && + ((node.contents as Model.Parameter).value as number) > + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_OUT_GAIN[0].min + ) { + store.dispatch( + storeFaderLevel( + ch - 1, + dbToFloat( + (node.contents as Model.Parameter) + .value as number + ) + ) + ) + global.mainThreadHandler.updatePartialStore(ch - 1) + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + ch - 1, + dbToFloat( + (node.contents as Model.Parameter) + .value as number + ) + ) + } + } + }) + } catch (e) { + logger.data(e).debug('error when subscribing to fader level') + } + } + async subscribeGainLevel( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const sourceName = this.faders[ch] + if (!sourceName) return + + const proto = + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_INPUT_GAIN[0] + let command = proto.mixerMessage.replace('{channel}', sourceName) + + try { + const node = await this.emberConnection.getElementByPath(command) + if (node.contents.type !== Model.ElementType.Parameter) return + + logger.debug(`Subscription of channel gain: ${command}`) + this.emberConnection.subscribe(node, () => { + logger.trace(`Receiving Gain from Ch ${ch}`) + const value = (node.contents as Model.Parameter).value as number + const level = (value - proto.min) / (proto.max - proto.min) + if ( + ((node.contents as Model.Parameter).value as number) > + proto.min + ) { + store.dispatch(storeInputGain(ch - 1, level)) + global.mainThreadHandler.updatePartialStore(ch - 1) + } + }) + } catch (e) { + logger.data(e).debug('Error when subscribing to gain level') + } + } + async subscribeInputSelector( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const sourceName = this.faders[ch] + if (!sourceName) return + + let command = this.mixerProtocol.channelTypes[ + typeIndex + ].fromMixer.CHANNEL_INPUT_SELECTOR[0].mixerMessage.replace( + '{channel}', + sourceName + ) + + try { + const node = await this.emberConnection.getElementByPath(command) + logger.debug(`set_cap ${ch} hasInputSel true`) + store.dispatch(storeCapability(ch - 1, 'hasInputSelector', true)) + if (node.contents.type !== Model.ElementType.Parameter) { + return + } + + logger.debug(`Subscription of channel input selector: ${command}`) + this.emberConnection.subscribe(node, () => { + logger.trace(`Receiving InpSelector from Ch ${ch}`) + this.mixerProtocol.channelTypes[ + typeIndex + ].fromMixer.CHANNEL_INPUT_SELECTOR.forEach((selector, i) => { + if ( + selector.value === + (node.contents as Model.Parameter).value + ) { + store.dispatch({ + type: SET_INPUT_SELECTOR, + channel: ch - 1, + selected: i + 1, + }) + global.mainThreadHandler.updatePartialStore(ch - 1) + } + }) + }) + } catch (e) { + if (e.message.match(/could not find node/i)) { + logger.debug(`set_cap ${ch} hasInputSel false`) + store.dispatch( + storeCapability(ch - 1, 'hasInputSelector', false) + ) + } + logger.data(e).debug('Error when subscribing to input selector') + } + } + async subscribeAMixState( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + const sourceName = this.faders[ch] + if (!sourceName) return + + let command = this.mixerProtocol.channelTypes[ + typeIndex + ].fromMixer.CHANNEL_AMIX[0].mixerMessage.replace( + '{channel}', + sourceName + ) + + try { + const node = await this.emberConnection.getElementByPath(command) + logger.debug(`set_cap ${ch - 1} hasAMix true`) + store.dispatch(storeCapability(ch - 1, 'hasAMix', true)) + if (node.contents.type !== Model.ElementType.Parameter) { + return + } + + logger.debug(`Subscription of AMix state: ${command}`) + this.emberConnection.subscribe(node, () => { + logger.trace(`Receiving AMix state from Ch ${ch}`) + store.dispatch( + storeSetAMix( + ch - 1, + (node.contents as Model.Parameter).value === 1 + ) + ) + global.mainThreadHandler.updatePartialStore(ch - 1) + }) + } catch (e) { + if (e.message.match(/could not find node/i)) { + logger.debug(`set_cap ${ch - 1} hasAMix false`) + store.dispatch(storeCapability(ch - 1, 'hasAMix', false)) + } + logger.data(e).debug('error when subscribing to input selector') + } + } + + subscribeChannelName() { + return true + } + + pingMixerCommand() { + return true + } + + sendOutMessage( + mixerMessage: string, + channel: number, + value: string | number | boolean, + type?: string + ) { + const channelString = this.faders[channel] + + if (!channelString) return + + let message = mixerMessage.replace('{channel}', channelString) + + this.emberConnection + .getElementByPath(message) + .then((element: any) => { + logger.trace(`Sending out message: ${message}`) + return this.emberConnection.setValue( + element, + typeof value === 'string' ? parseFloat(value) : value + ) + }) + .then((req) => req.response) + .catch((error: any) => { + logger.data(error).error('Ember Error ') + }) + } + + sendOutLevelMessage(channel: number, value: number) { + const source = this.faders[channel] + if (!channel) return + + const mixerMessage = + this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_OUT_GAIN[0] + .mixerMessage + + logger.trace(`Sending out Level: ${value} To ${source}`) + + this.sendOutMessage(mixerMessage, channel, value) + } + + updateOutLevel(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let protocol = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0] + let level = + (state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].outputLevel - + protocol.min) * + (protocol.max - protocol.min) + this.sendOutLevelMessage(channelTypeIndex + 1, level) + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let protocol = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0] + + const level = floatToDB(outputLevel) + + this.sendOutLevelMessage(channelTypeIndex + 1, level) + } + + async updatePflState(channelIndex: number) { + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + let channelType = channel.channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + + // fetch source name and function node + const fader = this.faders[channelTypeIndex + 1] + const fn = (await this.emberConnection.getElementByPath( + 'Ruby.Functions.SetPFLState' + )) as Model.NumberedTreeNode + + if (!fader || !fn) + throw new Error( + 'Oops could not find node or function to update PFL state' + ) + + try { + const { response } = await this.emberConnection.invoke( + fn, + { + value: fader, + type: Model.ParameterType.String, + }, + { + value: state.faders[0].fader[channelIndex].pflOn, + type: Model.ParameterType.Boolean, + } + ) + if (response) { + await response + } + } catch (e) { + logger.data(e).error('Ember Error ') + } + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + return true + } + + updateAMixState(channelIndex: number, amixOn: boolean) { + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + let channelType = channel.channelType + let channelTypeIndex = channel.channelTypeIndex + let protocol = + this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_AMIX[0] + + this.sendOutMessage( + protocol.mixerMessage, + channelTypeIndex + 1, + amixOn, + '' + ) + } + + updateNextAux(channelIndex: number, level: number) { + return true + } + + updateInputGain(channelIndex: number, gain: number) { + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + let channelType = channel.channelType + let channelTypeIndex = channel.channelTypeIndex + let protocol = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_INPUT_GAIN[0] + + let level = gain * (protocol.max - protocol.min) + protocol.min + + this.sendOutMessage( + protocol.mixerMessage, + channelTypeIndex + 1, + level, + '' + ) + } + updateInputSelector(channelIndex: number, inputSelected: number) { + logger.debug(`input select ${channelIndex} ${inputSelected}`) + const channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + let channelType = channel.channelType + let channelTypeIndex = channel.channelTypeIndex + let msg = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_INPUT_SELECTOR[inputSelected - 1] + + this.sendOutMessage( + msg.mixerMessage, + channelTypeIndex + 1, + msg.value, + '' + ) + return true + } + + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + return true + } + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + return true + } + + updateChannelName(channelIndex: number) { + return true + } + + loadMixerPreset(presetName: string) {} + + injectCommand(command: string[]) { + return true + } +} diff --git a/server/src/utils/mixerConnections/MidiMixerConnection.ts b/server/src/utils/mixerConnections/MidiMixerConnection.ts new file mode 100644 index 00000000..d6e896c7 --- /dev/null +++ b/server/src/utils/mixerConnections/MidiMixerConnection.ts @@ -0,0 +1,237 @@ +//Node Modules: +//@ts-ignore +import WebMidi from 'webmidi' + +import { store, state } from '../../reducers/store' +import { remoteConnections } from '../../mainClasses' + +//Utils: +import { MixerProtocolPresets } from '../../../../shared/src/constants/MixerProtocolPresets' +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { storeSetOutputLevel } from '../../../../shared/src/actions/channelActions' +import { storeFaderLevel, storeTogglePgm } from '../../../../shared/src/actions/faderActions' +import { logger } from '../logger' + +export class MidiMixerConnection { + store: any + mixerProtocol: any + mixerIndex: number + midiInput: any + midiOutput: any + + constructor(mixerProtocol: IMixerProtocol, mixerIndex: number) { + this.sendOutMessage = this.sendOutMessage.bind(this) + this.pingMixerCommand = this.pingMixerCommand.bind(this) + + this.mixerProtocol = mixerProtocol || MixerProtocolPresets.genericMidi + this.mixerIndex = mixerIndex + + WebMidi.enable((err: any) => { + if (err) { + logger.data(err).error('WebMidi could not be enabled.') + } + logger.info( + `Connecting Mixer Midi input on port: ${ + state.settings[0].mixers[this.mixerIndex].mixerMidiInputPort + }` + ) + logger.info( + `Connecting Mixer Midi output on port: ${ + state.settings[0].mixers[this.mixerIndex] + .mixerMidiOutputPort + }` + ) + this.midiInput = WebMidi.getInputByName( + state.settings[0].mixers[this.mixerIndex].mixerMidiInputPort + ) + this.midiOutput = WebMidi.getOutputByName( + state.settings[0].mixers[this.mixerIndex].mixerMidiOutputPort + ) + + this.setupMixerConnection() + }) + } + + setupMixerConnection() { + this.midiInput.addListener('controlchange', 1, (message: any) => { + logger.debug(`Received 'controlchange' message (${message.data}).`) + if ( + message.data[1] >= + parseInt( + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_OUT_GAIN[0].mixerMessage + ) && + message.data[1] <= + parseInt( + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_OUT_GAIN[0].mixerMessage + ) + + 24 + ) { + let ch = + 1 + + message.data[1] - + parseInt( + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_OUT_GAIN[0].mixerMessage + ) + let faderChannel = + 1 + + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader + store.dispatch( + storeFaderLevel(faderChannel - 1, message.data[2]) + ) + if (!state.faders[0].fader[faderChannel - 1].pgmOn) { + store.dispatch( + storeTogglePgm( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader - 1 + ) + ) + } + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + faderChannel - 1, + state.faders[0].fader[faderChannel - 1].faderLevel + ) + } + if (state.faders[0].fader[faderChannel - 1].pgmOn) { + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((channel: any, index: number) => { + if (channel.assignedFader === faderChannel - 1) { + this.updateOutLevel(index) + } + }) + } + } + }) + this.midiInput.addListener('noteon', 'all', (error: any) => { + logger.debug( + `Received 'noteon' message (${error.note.name}${error.note.octave}).` + ) + }) + + return true + } + + pingMixerCommand() { + //Ping OSC mixer if mixerProtocol needs it. + this.mixerProtocol.pingCommand.map((command: any) => { + this.sendOutMessage(command.mixerMessage, 0, command.value) + }) + } + + sendOutMessage(ctrlMessage: string, channel: number, value: string) { + if ( + ctrlMessage != 'none' && + 0 <= parseFloat(value) && + parseFloat(value) <= 127 + ) { + let ctrlMessageInt = parseInt(ctrlMessage) + channel - 1 + this.midiOutput.sendControlChange(ctrlMessageInt, value, 1) + } + } + + updateOutLevel(channelIndex: number) { + let faderIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].assignedFader + if (state.faders[0].fader[faderIndex].pgmOn) { + store.dispatch( + storeSetOutputLevel( + this.mixerIndex, + channelIndex, + state.faders[0].fader[faderIndex].faderLevel + ) + ) + } + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_OUT_GAIN[0] + .mixerMessage, + channelIndex + 1, + String( + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].outputLevel + ) + ) + /* Client mode is disabled + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_FADER_LEVEL[0].mixerMessage, + channelIndex+1, + state.faders[0].fader[channelIndex].faderLevel + ); + */ + } + + updatePflState(channelIndex: number) { + if (state.faders[0].fader[channelIndex].pflOn === true) { + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer.PFL_ON[0] + .mixerMessage, + channelIndex + 1, + this.mixerProtocol.channelTypes[0].toMixer.PFL_ON[0].value + ) + } else { + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer.PFL_OFF[0] + .mixerMessage, + channelIndex + 1, + this.mixerProtocol.channelTypes[0].toMixer.PFL_OFF[0].value + ) + } + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + return true + } + + updateNextAux(channelIndex: number, level: number) { + return true + } + + updateInputGain(channelIndex: number, level: number) { + return true + } + updateInputSelector(channelIndex: number, inputSelected: number) { + return true + } + + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + return true + } + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + return true + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_OUT_GAIN[0] + .mixerMessage, + channelIndex + 1, + String(outputLevel) + ) + } + + updateChannelName(channelIndex: number) { + let channelName = state.faders[0].fader[channelIndex].label + this.sendOutMessage( + this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_NAME[0] + .mixerMessage, + channelIndex + 1, + channelName + ) + } + + loadMixerPreset(presetName: string) {} + + injectCommand(command: string[]) { + return true + } +} diff --git a/server/src/utils/mixerConnections/OscMixerConnection.ts b/server/src/utils/mixerConnections/OscMixerConnection.ts new file mode 100644 index 00000000..b6613fb6 --- /dev/null +++ b/server/src/utils/mixerConnections/OscMixerConnection.ts @@ -0,0 +1,780 @@ +//Node Modules: +import osc from 'osc' +import fs from 'fs' +import path from 'path' + +import { store, state } from '../../reducers/store' +import { mixerGenericConnection, remoteConnections } from '../../mainClasses' + +//Utils: +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { behringerXrMeter } from './productSpecific/behringerXr' +import { midasMeter } from './productSpecific/midas' +import { + storeSetAuxLevel, + storeSetChLabel, + storeSetOutputLevel, +} from '../../../../shared/src/actions/channelActions' +import { + storeFaderLevel, + storeFaderFx, + storeTogglePgm, + storeSetMute, +} from '../../../../shared/src/actions/faderActions' +import { storeSetMixerOnline } from '../../../../shared/src/actions/settingsActions' +import { logger } from '../logger' +import { sendVuLevel } from '../vuServer' +import { VuType } from '../../../../shared/src/utils/vu-server-types' + +interface IOscCommand { + address: string + args?: any[] +} + +export class OscMixerConnection { + mixerProtocol: IMixerProtocol + mixerIndex: number + cmdChannelIndex: number + oscConnection: any + mixerOnlineTimer: NodeJS.Timeout + timeoutTimer: NodeJS.Timeout + commandBuffer: IOscCommand[] = [] + + constructor(mixerProtocol: IMixerProtocol, mixerIndex: number) { + this.sendOutMessage = this.sendOutMessage.bind(this) + this.pingMixerCommand = this.pingMixerCommand.bind(this) + + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + + this.mixerProtocol = mixerProtocol + this.mixerIndex = mixerIndex + //If default store has been recreated multiple mixers are not created + if (!state.channels[0].chMixerConnection[this.mixerIndex]) { + state.channels[0].chMixerConnection[this.mixerIndex] = { + channel: [], + } + } + + this.cmdChannelIndex = + this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage + .split('/') + .findIndex((ch) => ch === '{channel}') + + this.oscConnection = new osc.UDPPort({ + localAddress: state.settings[0].mixers[this.mixerIndex].localIp, + localPort: parseInt( + state.settings[0].mixers[this.mixerIndex].localOscPort + '' + ), + remoteAddress: state.settings[0].mixers[this.mixerIndex].deviceIp, + remotePort: parseInt( + state.settings[0].mixers[this.mixerIndex].devicePort + '' + ), + }) + this.setupMixerConnection() + } + + mixerOnline(onLineState: boolean) { + store.dispatch(storeSetMixerOnline(this.mixerIndex, onLineState)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex, onLineState) + } + + setupMixerConnection() { + this.oscConnection + .on('ready', () => { + logger.info('Receiving state of desk') + this.initialCommands() + + this.mixerOnline(true) + global.mainThreadHandler.updateFullClientStore() + }) + .on('message', (message: any) => { + clearTimeout(this.mixerOnlineTimer) + if (!state.settings[0].mixers[this.mixerIndex].mixerOnline) { + logger.info( + `Audio Mixer number: ${this.mixerIndex + 1} is Online` + ) + this.mixerOnline(true) + } + logger.trace(`Received OSC message: ${message.address}`) + + if ( + this.checkOscCommand( + message.address, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_VU?.[0].mixerMessage + ) + ) { + if ( + state.settings[0].mixers[ + this.mixerIndex + ].mixerProtocol.includes('behringer') + ) { + behringerXrMeter(this.mixerIndex, message.args) + } else if ( + state.settings[0].mixers[ + this.mixerIndex + ].mixerProtocol.includes('midas') + ) { + this.resetMixerTimeout() + midasMeter(this.mixerIndex, message.args) + } else { + let ch = + message.address.split('/')[this.cmdChannelIndex] + sendVuLevel( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader, + VuType.Channel, + 0, + message.args[0] + ) + } + } else if ( + this.checkOscCommand( + message.address, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_VU_REDUCTION?.[0].mixerMessage + ) + ) { + let ch = message.address.split('/')[this.cmdChannelIndex] + sendVuLevel( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader, + VuType.Reduction, + 0, + message.args[0] + ) + } else if ( + this.checkOscCommand( + message.address, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_OUT_GAIN?.[0].mixerMessage + ) + ) { + let ch = message.address.split('/')[this.cmdChannelIndex] + let assignedFaderIndex = + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader + + if ( + assignedFaderIndex >= 0 && + !state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].fadeActive + ) { + if ( + message.args[0] > this.mixerProtocol.fader.min || + message.args[0] > + state.settings[0].autoResetLevel / 100 + ) { + store.dispatch( + storeFaderLevel( + assignedFaderIndex, + message.args[0] + ) + ) + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach( + ( + item: { assignedFader: any }, + index: number + ) => { + if ( + item.assignedFader === + assignedFaderIndex + ) { + store.dispatch( + storeSetOutputLevel( + this.mixerIndex, + index, + message.args[0] + ) + ) + } + } + ) + if ( + !state.faders[0].fader[assignedFaderIndex].pgmOn + ) { + if ( + message.args[0] > + this.mixerProtocol.fader.min || + 0 + ) { + store.dispatch( + storeTogglePgm(assignedFaderIndex) + ) + } + } + } else if ( + state.faders[0].fader[assignedFaderIndex].pgmOn || + state.faders[0].fader[assignedFaderIndex].voOn + ) { + store.dispatch( + storeFaderLevel( + assignedFaderIndex, + message.args[0] + ) + ) + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach( + ( + item: { assignedFader: any }, + index: number + ) => { + if ( + item.assignedFader === + assignedFaderIndex + ) { + store.dispatch( + storeSetOutputLevel( + this.mixerIndex, + index, + message.args[0] + ) + ) + } + } + ) + } + global.mainThreadHandler.updatePartialStore( + assignedFaderIndex + ) + mixerGenericConnection.updateOutLevel( + assignedFaderIndex, + 0, + this.mixerIndex + ) + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + assignedFaderIndex, + message.args[0] + ) + } + } + } else if ( + this.checkOscCommand( + message.address, + this.mixerProtocol.channelTypes?.[0].fromMixer + .AUX_LEVEL?.[0].mixerMessage + ) + ) { + let commandArray: string[] = + this.mixerProtocol.channelTypes[0].fromMixer.AUX_LEVEL[0].mixerMessage.split( + '/' + ) + let messageArray: string[] = message.address.split('/') + let ch = 0 + let auxIndex = 0 + + commandArray.forEach( + (commandPart: string, index: number) => { + if (commandPart === '{channel}') { + ch = parseFloat(messageArray[index]) + } else if (commandPart === '{argument}') { + auxIndex = parseFloat(messageArray[index]) - 1 + } + } + ) + if ( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].auxLevel[auxIndex] > -1 + ) { + logger.trace( + `Aux Message Channel: ${ch}\n Aux Index: ${auxIndex}\n Level: ${message.args[0]}` + ) + store.dispatch( + storeSetAuxLevel( + this.mixerIndex, + ch - 1, + auxIndex, + message.args[0] + ) + ) + global.mainThreadHandler.updateFullClientStore() + if (remoteConnections) { + remoteConnections.updateRemoteAuxPanels() + } + } + } else if ( + this.checkOscCommand( + message.address, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_NAME?.[0].mixerMessage + ) + ) { + let ch = message.address.split('/')[this.cmdChannelIndex] + store.dispatch( + storeSetChLabel( + this.mixerIndex, + ch - 1, + message.args[0] + ) + ) + global.mainThreadHandler.updatePartialStore( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader + ) + } else if ( + this.checkOscCommand( + message.address, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_MUTE_ON?.[0].mixerMessage + ) + ) { + let ch = message.address.split('/')[this.cmdChannelIndex] + store.dispatch( + storeSetMute( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader, + message.args[0] === 0 + ) + ) + mixerGenericConnection.updateMuteState( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader, + this.mixerIndex + ) + global.mainThreadHandler.updatePartialStore( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader + ) + } else { + this.checkFxCommands(message) + logger.trace(`Unknown OSC message: ${message.address}`) + } + }) + .on('error', (error: any) => { + global.mainThreadHandler.updateFullClientStore() + logger.error(`Error: ${error}`) + }) + .on('disconnect', () => { + this.mixerOnline(false) + logger.info('Lost OSC connection') + }) + + this.oscConnection.open() + logger.info( + `OSC listening on port ${ + state.settings[0].mixers[this.mixerIndex].localOscPort + }` + ) + + //Ping OSC mixer if mixerProtocol needs it. + if (this.mixerProtocol.pingTime > 0) { + let oscTimer = setInterval(() => { + this.pingMixerCommand() + logger.debug(`Send buffer Size: ${this.commandBuffer.length}`) + }, this.mixerProtocol.pingTime) + } + + //Setup Buffer Timer: + setInterval(() => { + if (this.commandBuffer.length > 0) { + this.oscConnection.send(this.commandBuffer.shift()) + } + }, 2) + } + + initialCommands() { + // To prevent network overload, timers will delay the requests. + this.mixerProtocol.initializeCommands?.forEach( + (item, itemIndex: number) => { + setTimeout(() => { + if (item.mixerMessage.includes('{channel}')) { + if (item.type !== undefined && item.type === 'aux') { + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((channel: any) => { + channel.auxLevel.forEach( + (auxLevel: any, auxIndex: number) => { + if (channel.assignedFader >= 0) { + if ( + state.faders[0].fader[ + channel.assignedFader + ] + ) { + setTimeout(() => { + this.sendOutRequestAux( + item.mixerMessage, + auxIndex + 1, + state.faders[0].fader[ + channel + .assignedFader + ].monitor + ) + }, state.faders[0].fader[channel.assignedFader].monitor * 10 + auxIndex * 100) + } + } + } + ) + }) + } else { + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((channel: any, index: any) => { + this.sendOutRequest( + item.mixerMessage, + index + 1 + ) + }) + } + } else { + let value = item.value || 0 + let type = item.type || 'i' + this.sendOutMessage(item.mixerMessage, 1, value, type) + } + }, itemIndex * 100) + } + ) + } + + pingMixerCommand() { + //Ping OSC mixer if mixerProtocol needs it. + this.mixerProtocol.pingCommand.forEach((command) => { + let value = command.value || 0 + let type = command.type || 'i' + this.sendOutMessage(command.mixerMessage, 0, value, type) + }) + global.mainThreadHandler.updateFullClientStore() + this.mixerOnlineTimer = setTimeout(() => { + logger.warn(`Audio Mixer number: ${this.mixerIndex + 1} is Offline`) + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + }, this.mixerProtocol.pingTime) + } + + resetMixerTimeout() { + // Check mixer Timeout response if protocol needs it: + if (this.mixerProtocol.mixerTimeout > 0) { + clearTimeout(this.timeoutTimer) + this.timeoutTimer = setTimeout(() => { + logger.warn( + `Audio Mixer number: ${this.mixerIndex + 1} timeout` + ) + }, this.mixerProtocol.mixerTimeout) + } + } + + checkFxCommands(message: any) { + Object.keys(fxParamsList).forEach((keyName: string) => { + if (!isNaN(parseFloat(keyName))) { + return + } + + let fxKey = keyName as keyof typeof fxParamsList + let fxMessage = + this.mixerProtocol.channelTypes[0].fromMixer[ + fxParamsList[fxKey] + ][0] + let range: number = fxMessage.max - fxMessage.min || 1 + if (this.checkOscCommand(message.address, fxMessage.mixerMessage)) { + let ch = message.address.split('/')[this.cmdChannelIndex] + + store.dispatch( + storeFaderFx( + fxParamsList[fxKey], + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader, + message.args[0] / range + ) + ) + global.mainThreadHandler.updatePartialStore( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader + ) + } + + logger.trace(fxKey) + }) + } + + checkOscCommand(message: string, command: string | undefined): boolean { + if (!command) return false + if (message === command) return true + let messageArray: string[] = message.split('/') + let commandArray: string[] = command.split('/') + let status: boolean = true + if (messageArray.length !== commandArray.length) { + return false + } + commandArray.forEach((commandPart: string, index: number) => { + if (commandPart === '{channel}') { + if (typeof parseFloat(messageArray[index]) !== 'number') { + status = false + } + } else if (commandPart === '{argument}') { + if (typeof parseFloat(messageArray[index]) !== 'number') { + status = false + } + } else if (commandPart !== messageArray[index]) { + status = false + } + }) + return status + } + + sendOutMessage( + oscMessage: string, + channel: number, + value: string | number, + type: string + ) { + let channelString = this.mixerProtocol.leadingZeros + ? ('0' + channel).slice(-2) + : channel.toString() + let message = oscMessage.replace('{channel}', channelString) + if (message != 'none') { + logger.trace(`Sending OSC command: ${message}`) + this.sendBuffered({ + address: message, + args: [ + { + type: type, + value: value, + }, + ], + }) + } + } + + sendOutRequest(oscMessage: string, channel: number) { + let channelString = this.mixerProtocol.leadingZeros + ? ('0' + channel).slice(-2) + : channel.toString() + let message = oscMessage.replace('{channel}', channelString) + if (message != 'none') { + this.sendBuffered({ + address: message, + }) + } + } + + sendOutRequestAux(oscMessage: string, channel: number, auxSend: number) { + let channelString = this.mixerProtocol.leadingZeros + ? ('0' + channel).slice(-2) + : channel.toString() + let message = oscMessage.replace('{channel}', channelString) + let auxSendNumber = this.mixerProtocol.leadingZeros + ? ('0' + String(auxSend)).slice(-2) + : String(auxSend) + message = message.replace('{argument}', auxSendNumber) + logger.trace(`Initial Aux Message: ${message}`) + if (message != 'none') { + this.sendBuffered({ + address: message, + }) + } + } + + updateOutLevel(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage, + channelTypeIndex + 1, + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].outputLevel, + 'f' + ) + } + + updatePflState(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + if (state.faders[0].fader[channelIndex].pflOn === true) { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .mixerMessage, + channelTypeIndex + 1, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .value, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .type + ) + } else { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .mixerMessage, + channelTypeIndex + 1, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .value, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .type + ) + } + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + if (muteOn === true) { + let mute = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_ON[0] + this.sendOutMessage( + mute.mixerMessage, + channelTypeIndex + 1, + mute.value, + mute.type + ) + } else { + let mute = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_OFF[0] + this.sendOutMessage( + mute.mixerMessage, + channelTypeIndex + 1, + mute.value, + mute.type + ) + } + } + + updateNextAux(channelIndex: number, level: number) { + this.updateAuxLevel( + channelIndex, + state.settings[0].mixers[this.mixerIndex].nextSendAux - 1, + level + ) + } + + updateInputGain(channelIndex: number, level: number) { + return true + } + updateInputSelector(channelIndex: number, inputSelected: number) { + return true + } + + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let fx = + this.mixerProtocol.channelTypes[channelType].toMixer[fxParam][0] + this.sendOutMessage(fx.mixerMessage, channelTypeIndex + 1, level, 'f') + } + + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + 1 + let auxSendCmd = + this.mixerProtocol.channelTypes[channelType].toMixer.AUX_LEVEL[0] + let auxSendNumber = this.mixerProtocol.leadingZeros + ? ('0' + String(auxSendIndex + 1)).slice(-2) + : String(auxSendIndex + 1) + let message = auxSendCmd.mixerMessage.replace( + '{argument}', + auxSendNumber + ) + + this.sendOutMessage(message, channel, level, 'f') + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage, + channelTypeIndex + 1, + String(outputLevel), + 'f' + ) + } + + updateChannelName(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let channelName = state.faders[0].fader[channelIndex].label + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_NAME[0] + .mixerMessage, + channelTypeIndex + 1, + channelName, + 's' + ) + } + + loadMixerPreset(presetName: string) { + logger.info(`Loading preset: ${presetName}`) + if (this.mixerProtocol.presetFileExtension === 'X32') { + let data = JSON.parse( + fs.readFileSync( + path.resolve(process.cwd(), 'storage', presetName), + 'utf8' + ) + ) + + this.sendBuffered({ + address: this.mixerProtocol.loadPresetCommand[0].mixerMessage, + args: [ + { + type: 's', + value: 'scene', + }, + { + type: 'i', + value: parseInt(data.sceneIndex), + }, + ], + }) + setTimeout(() => { + this.initialCommands() + }, 1000) + } + } + + sendBuffered(command: IOscCommand) { + this.commandBuffer.push(JSON.parse(JSON.stringify(command))) + } + + injectCommand(command: string[]) { + return true + } +} diff --git a/server/src/utils/mixerConnections/SSLMixerConnection.ts b/server/src/utils/mixerConnections/SSLMixerConnection.ts new file mode 100644 index 00000000..eeb1de6d --- /dev/null +++ b/server/src/utils/mixerConnections/SSLMixerConnection.ts @@ -0,0 +1,519 @@ +//Node Modules: +import net from 'net' +import { store, state } from '../../reducers/store' +import { mixerGenericConnection, remoteConnections } from '../../mainClasses' + +//Utils: +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { storeSetOutputLevel } from '../../../../shared/src/actions/channelActions' +import { + storeFaderLevel, + storeSetMute, + storeTogglePgm, +} from '../../../../shared/src/actions/faderActions' +import { storeSetMixerOnline } from '../../../../shared/src/actions/settingsActions' +import { logger } from '../logger' + +export class SSLMixerConnection { + mixerProtocol: IMixerProtocol + mixerIndex: number + cmdChannelIndex: number + SSLConnection: any + mixerOnlineTimer: any + + constructor(mixerProtocol: IMixerProtocol, mixerIndex: number) { + this.sendOutLevelMessage = this.sendOutLevelMessage.bind(this) + + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + + this.mixerProtocol = mixerProtocol + this.mixerIndex = mixerIndex + + this.cmdChannelIndex = + this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage + .split('/') + .findIndex((ch) => ch === '{channel}') + + this.SSLConnection = new net.Socket() + this.SSLConnection.connect( + state.settings[0].mixers[this.mixerIndex].devicePort, + state.settings[0].mixers[this.mixerIndex].deviceIp, + () => { + logger.info('Connected to SSL') + } + ) + this.setupMixerConnection() + } + + formatHexWithSpaces(str: string, item: string, every: number) { + for (let i = 0; i < str.length; i++) { + if (!(i % (every + 1))) { + str = str.substring(0, i) + item + str.substring(i) + } + } + return str.substring(1) + } + + handleReceivedFaderLevelCommand = (buffer: any) => { + try { + let channelIndex = buffer[6] + let value = buffer.readUInt16BE(7) / 1024 + const ch = state.channels[0].chMixerConnection[this.mixerIndex].channel + + if ( + !ch[channelIndex].fadeActive + ) { + if ( + value > + this.mixerProtocol.fader.min + + (this.mixerProtocol.fader.max * + state.settings[0].autoResetLevel) / + 100 + ) { + if ( + ch[channelIndex].outputLevel !== value + ) { + store.dispatch( + storeFaderLevel(ch[channelIndex].assignedFader, value) + ) + if (!state.faders[0].fader[ch[channelIndex].assignedFader].pgmOn) { + store.dispatch(storeTogglePgm(ch[channelIndex].assignedFader)) + } + + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + ch[channelIndex].assignedFader, + value + ) + } + if (state.faders[0].fader[ch[channelIndex].assignedFader].pgmOn) { + ch.forEach((channel: any, index: number) => { + if ( + channel.assignedFader === ch[channelIndex].assignedFader + ) { + this.updateOutLevel(index) + + } + }) + } + } + } else if ( + state.faders[0].fader[ch[channelIndex].assignedFader].pgmOn || + state.faders[0].fader[ch[channelIndex].assignedFader].voOn + ) { + store.dispatch(storeFaderLevel(ch[channelIndex].assignedFader, value)) + ch.forEach( + (item: { assignedFader: any }, index: number) => { + if (item.assignedFader === ch[channelIndex].assignedFader) { + store.dispatch( + storeSetOutputLevel( + this.mixerIndex, + index, + value + ) + ) + } + } + ) + } + global.mainThreadHandler.updatePartialStore(ch[channelIndex].assignedFader) + mixerGenericConnection.updateOutLevel(ch[channelIndex].assignedFader, 0, this.mixerIndex) + } + } catch (error) { + logger.error( + 'Error translating received message :' + String(error), + {} + ) + } + } + + handleReceivedMuteCommand = (buffer: any) => { + // MUTE ON/OFF COMMAND + let commandHex = buffer.toString('hex') + let channelIndex = buffer[6] + let value: boolean = buffer[7] === 0 ? true : false + logger.trace( + `Receive Buffer Channel On/off: ${this.formatHexWithSpaces( + commandHex, + ' ', + 2 + )}` + ) + + let assignedFaderIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].assignedFader + + store.dispatch(storeSetMute(assignedFaderIndex, value)) + + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + assignedFaderIndex, + value ? 1 : 0 + ) + } + state.channels[0].chMixerConnection[this.mixerIndex].channel.forEach( + (channel: any, index: number) => { + if ( + channel.assignedFader === assignedFaderIndex && + index !== channelIndex + ) { + this.updateMuteState( + index, + state.faders[0].fader[assignedFaderIndex].muteOn + ) + } + } + ) + mixerGenericConnection.updateMuteState(assignedFaderIndex, this.mixerIndex) + global.mainThreadHandler.updatePartialStore(assignedFaderIndex) + } + + setupMixerConnection() { + // Return command was an acknowledge: + let lastWasAck = false + + this.SSLConnection.on('ready', () => { + store.dispatch(storeSetMixerOnline(this.mixerIndex, true)) + + logger.info('Receiving state of desk', {}) + this.mixerProtocol.initializeCommands.forEach((item) => { + if (item.mixerMessage.includes('{channel}')) { + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((channel: any, index: any) => { + this.sendOutRequest(item.mixerMessage, index) + }) + } else { + this.sendOutLevelMessage(item.mixerMessage, 0, item.value) + } + }) + global.mainThreadHandler.updateFullClientStore() + }) + .on('data', (data: any) => { + clearTimeout(this.mixerOnlineTimer) + store.dispatch(storeSetMixerOnline(this.mixerIndex, true)) + + let buffers = [] + let lastIndex = 0 + for (let index = 1; index < data.length; index++) { + if (data[index] === 241) { + buffers.push(data.slice(lastIndex, index - 1)) + lastIndex = index + } + } + if (buffers.length === 0) { + buffers.push(data) + } + + buffers.forEach((buffer) => { + if (buffer[1] === 6 && buffer[2] === 255 && !lastWasAck) { + lastWasAck = false + // FADERLEVEL COMMAND: + this.handleReceivedFaderLevelCommand(buffer) + } else if ( + buffer[1] === 5 && + buffer[2] === 255 && + buffer[4] === 1 && + !lastWasAck + ) { + lastWasAck = false + // MUTE ON/OFF COMMAND + this.handleReceivedMuteCommand(buffer) + } else { + // UNKNOWN COMMAND + let commandHex = buffer.toString('hex') + logger.trace( + `Receieve Buffer Hex: ${this.formatHexWithSpaces( + commandHex, + ' ', + 2 + )}` + ) + } + if (buffer[0] === 4) { + lastWasAck = true + } else { + lastWasAck = false + } + }) + }) + .on('error', (error: any) => { + logger.error(`Error: ${error}`) + logger.info('Lost SCP connection') + }) + + //Ping mixer to get mixerOnlineState + let oscTimer = setInterval(() => { + this.pingMixerCommand() + }, this.mixerProtocol.pingTime) + } + + pingMixerCommand() { + //Ping OSC mixer if mixerProtocol needs it. + this.mixerProtocol.pingCommand.forEach((command) => { + this.sendOutPingRequest() + }) + global.mainThreadHandler.updateFullClientStore() + this.mixerOnlineTimer = setTimeout(() => { + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + }, this.mixerProtocol.pingTime) + } + + checkSSLCommand(message: string, command: string) { + if (!message) return false + if (message.slice(0, command.length) === command) return true + return false + } + + calculate_checksum8(hexValues: string) { + // convert input value to upper case + hexValues = hexValues.toUpperCase() + + let strHex = new String('0123456789ABCDEF') + let result = 0 + let fctr = 16 + + for (let i = 0; i < hexValues.length; i++) { + if (hexValues.charAt(i) == ' ') continue + + let v = strHex.indexOf(hexValues.charAt(i)) + if (v < 0) { + result = -1 + break + } + result += v * fctr + + if (fctr == 16) fctr = 1 + else fctr = 16 + } + + // Calculate 2's complement + result = (~(result & 0xff) + 1) & 0xff + // Convert result to string + return ( + strHex.charAt(Math.floor(result / 16)) + strHex.charAt(result % 16) + ) + } + + sendOutLevelMessage( + sslMessage: string, + channelIndex: number, + value: string | number + ) { + let valueNumber: number + if (typeof value === 'string') { + value = parseFloat(value) + } + if (value < 0) { + value = 0 + } + valueNumber = value * 1024 + let valueByte = new Uint8Array([ + (valueNumber & 0x0000ff00) >> 8, + valueNumber & 0x000000ff, + ]) + + let channelByte = new Uint8Array([ + (channelIndex & 0x0000ff00) >> 8, + channelIndex & 0x000000ff, + ]) + + sslMessage = sslMessage.replace( + '{channel}', + ('0' + channelByte[0].toString(16)).slice(-2) + + ' ' + + ('0' + channelByte[1].toString(16)).slice(-2) + ) + sslMessage = sslMessage.replace( + '{level}', + ('0' + valueByte[0].toString(16)).slice(-2) + + ' ' + + ('0' + valueByte[1].toString(16)).slice(-2) + + ' ' + ) + sslMessage = sslMessage + this.calculate_checksum8(sslMessage.slice(9)) + let a = sslMessage.split(' ') + let buf = Buffer.from( + a.map((val: string) => { + return parseInt(val, 16) + }) + ) + + logger.trace(`Send HEX: ${sslMessage}`) + this.SSLConnection.write(buf) + } + + sendOutRequest(sslMessage: string, channelIndex: number) { + //let sslMessage = 'f1 06 00 80 00 00 {channel} {level}' + let channelByte = new Uint8Array([ + (channelIndex & 0x0000ff00) >> 8, + channelIndex & 0x000000ff, + ]) + sslMessage = sslMessage.replace( + '{channel}', + ('0' + channelByte[0].toString(16)).slice(-2) + + ' ' + + ('0' + channelByte[1].toString(16)).slice(-2) + ) + sslMessage = + sslMessage + ' ' + this.calculate_checksum8(sslMessage.slice(9)) + let a = sslMessage.split(' ') + let buf = Buffer.from( + a.map((val: string) => { + return parseInt(val, 16) + }) + ) + + logger.trace(`Send HEX: ${sslMessage}`) + this.SSLConnection.write(buf) + } + + sendOutPingRequest() { + let sslMessage = 'f1 02 00 07 00' + sslMessage = + sslMessage + ' ' + this.calculate_checksum8(sslMessage.slice(9)) + let a = sslMessage.split(' ') + let buf = Buffer.from( + a.map((val: string) => { + return parseInt(val, 16) + }) + ) + + logger.trace(`Send HEX: ${sslMessage}`) + this.SSLConnection.write(buf) + } + + updateOutLevel(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let faderIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].assignedFader + if (state.faders[0].fader[faderIndex].pgmOn) { + store.dispatch( + storeSetOutputLevel( + this.mixerIndex, + channelIndex, + state.faders[0].fader[faderIndex].faderLevel + ) + ) + } + this.sendOutLevelMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage, + channelTypeIndex, + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].outputLevel + ) + } + + updatePflState(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + if (state.faders[0].fader[channelIndex].pflOn === true) { + this.sendOutRequest( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .mixerMessage, + channelTypeIndex + ) + } else { + this.sendOutRequest( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .mixerMessage, + channelTypeIndex + ) + } + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + if (muteOn === true) { + this.sendOutRequest( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_ON[0].mixerMessage, + channelTypeIndex + ) + } else { + this.sendOutRequest( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_OFF[0].mixerMessage, + channelTypeIndex + ) + } + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + this.sendOutLevelMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage, + channelTypeIndex, + String(outputLevel) + ) + } + + updateNextAux(channelIndex: number, level: number) { + this.sendOutLevelMessage( + this.mixerProtocol.channelTypes[0].toMixer.NEXT_SEND[0] + .mixerMessage, + channelIndex + 128, + level + ) + } + + updateInputGain(channelIndex: number, level: number) { + return true + } + updateInputSelector(channelIndex: number, inputSelected: number) { + return true + } + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + return true + } + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + return true + } + + updateChannelName(channelIndex: number) { + return true + } + + loadMixerPreset(presetName: string) {} + + injectCommand(command: string[]) { + return true + } +} diff --git a/server/src/utils/mixerConnections/StuderMixerConnection.ts b/server/src/utils/mixerConnections/StuderMixerConnection.ts new file mode 100644 index 00000000..6224de15 --- /dev/null +++ b/server/src/utils/mixerConnections/StuderMixerConnection.ts @@ -0,0 +1,387 @@ +//@ts-ignore +import { EmberClient } from 'node-emberplus' +import { store, state } from '../../reducers/store' +import { remoteConnections } from '../../mainClasses' + +//Utils: +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { storeFaderLevel } from '../../../../shared/src/actions/faderActions' +import { logger } from '../logger' +import { storeSetChLabel } from '../../../../shared/src/actions/channelActions' + +export class StuderMixerConnection { + mixerProtocol: IMixerProtocol + mixerIndex: number + emberConnection: any + deviceRoot: any + emberNodeObject: Array + + constructor(mixerProtocol: IMixerProtocol, mixerIndex: number) { + this.sendOutMessage = this.sendOutMessage.bind(this) + this.pingMixerCommand = this.pingMixerCommand.bind(this) + + this.emberNodeObject = new Array(200) + this.mixerProtocol = mixerProtocol + this.mixerIndex = mixerIndex + + logger.info('Setting up Ember connection') + this.emberConnection = new EmberClient({ + host: state.settings[0].mixers[this.mixerIndex].deviceIp, + port: state.settings[0].mixers[this.mixerIndex].devicePort, + }) + + this.emberConnection.on('error', (error: any) => { + if ( + (error.message + '').match(/econnrefused/i) || + (error.message + '').match(/disconnected/i) + ) { + logger.error('Ember connection not establised') + } else { + logger + .data(error) + .error(`Ember connection unknown error: ${error.message}`) + } + }) + this.emberConnection.on('disconnected', () => { + logger.error('Lost Ember connection') + }) + logger.info('Connecting to Ember') + let deviceRoot: any + this.emberConnection + .connect() + .then(() => { + this.setupMixerConnection() + }) + .catch((e: any) => { + logger.error(e.stack) + }) + } + + setupMixerConnection() { + logger.info( + 'Ember connection established - setting up subscription of channels' + ) + + let ch: number = 1 + state.settings[0].mixers[ + this.mixerIndex + ].numberOfChannelsInType.forEach((numberOfChannels, typeIndex) => { + for ( + let channelTypeIndex = 0; + channelTypeIndex < numberOfChannels; + channelTypeIndex++ + ) { + this.subscribeFaderLevel(ch, typeIndex, channelTypeIndex) + ch++ + } + }) + /* + .CHANNEL_VU)){ + store.dispatch({ + type:SET_VU_LEVEL, + channel: ch - 1, + level: message.args[0] + }); + */ + + //Ping OSC mixer if mixerProtocol needs it. + if (this.mixerProtocol.pingTime > 0) { + let emberTimer = setInterval(() => { + this.pingMixerCommand() + }, this.mixerProtocol.pingTime) + } + } + + subscribeFaderLevel( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + let command = this.mixerProtocol.channelTypes[ + typeIndex + ].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage.replace( + '{channel}', + String(channelTypeIndex + 1) + ) + this.emberConnection + .getElementByPath(command) + .then((node: any) => { + logger.info(`Subscription of channel: ${command}`) + this.emberNodeObject[ch - 1] = node + this.emberConnection.subscribe(node, () => { + logger.trace(`Receiving Level from Ch ${ch}`) + if ( + !state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].fadeActive && + !state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].fadeActive && + node.contents.value > + this.mixerProtocol.channelTypes[typeIndex].fromMixer + .CHANNEL_OUT_GAIN[0].min + ) { + store.dispatch( + storeFaderLevel(ch - 1, node.contents.value) + ) + global.mainThreadHandler.updatePartialStore(ch - 1) + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + ch - 1, + node.contents.value + ) + } + } + }) + }) + .catch((error: any) => { + logger.error(error) + }) + } + + subscribeChannelName( + ch: number, + typeIndex: number, + channelTypeIndex: number + ) { + this.emberConnection + .getNodeByPath( + this.mixerProtocol.channelTypes[ + typeIndex + ].fromMixer.CHANNEL_NAME[0].mixerMessage.replace( + '{channel}', + String(channelTypeIndex + 1) + ) + ) + .then((node: any) => { + this.emberConnection.subscribe(node, () => { + store.dispatch( + storeSetChLabel( + this.mixerIndex, + ch - 1, + node.contents.value + ) + ) + }) + }) + } + + pingMixerCommand() { + //Ping Ember mixer if mixerProtocol needs it. + return + this.mixerProtocol.pingCommand.map((command) => { + this.sendOutMessage( + command.mixerMessage, + 0, + command.value, + command.type + ) + }) + } + + sendOutMessage( + mixerMessage: string, + channel: number, + value: string | number, + type: string + ) { + let channelString = this.mixerProtocol.leadingZeros + ? ('0' + channel).slice(-2) + : channel.toString() + + let message = mixerMessage.replace('{channel}', channelString) + + /* + this.emberConnection.getElementByPath(message) + .then((element: any) => { + logger.trace(`Sending out message: ${message}`) + this.emberConnection.setValue( + this.emberNodeObject[channel-1], + typeof value === 'number' ? value : parseFloat(value) + ) + }) + .catch((error: any) => { + logger.data(error).error("Ember Error") + }) + */ + } + + sendOutLevelMessage(channel: number, value: number) { + let levelMessage: string + let channelVal: number + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channel - 1 + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channel - 1 + ].channelTypeIndex + + if (channel < 25) { + levelMessage = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage + channelVal = 160 + channelTypeIndex + 1 + } else { + levelMessage = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[1].mixerMessage + channelVal = channelTypeIndex + 1 + } + + let valueNumber = value + let valueByte = new Uint8Array([ + (valueNumber & 0x0000ff00) >> 8, + valueNumber & 0x000000ff, + ]) + let channelByte = new Uint8Array([channelVal & 0x000000ff]) + + levelMessage = levelMessage.replace( + '{channel}', + ('0' + channelByte[0].toString(16)).slice(-2) + ) + levelMessage = levelMessage.replace( + '{level}', + ('0' + valueByte[0].toString(16)).slice(-2) + + ' ' + + ('0' + valueByte[1].toString(16)).slice(-2) + ) + + let hexArray = levelMessage.split(' ') + let buf = Buffer.from( + hexArray.map((val: string) => { + return parseInt(val, 16) + }) + ) + this.emberConnection._client.socket.write(buf) + logger.trace(`Send HEX: ${levelMessage}`) + } + + sendOutRequest(mixerMessage: string, channel: number) { + let channelString = this.mixerProtocol.leadingZeros + ? ('0' + channel).slice(-2) + : channel.toString() + let message = mixerMessage.replace('{channel}', channelString) + if (message != 'none') { + /* + this.oscConnection.send({ + address: message + }); +*/ + } + } + + updateOutLevel(channelIndex: number) { + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let outputlevel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].outputLevel + let level = 20 * Math.log((1.3 * outputlevel) / 0.775) + if (level < -90) { + level = -90 + } + // logger.debug(`Log level: ${level}`) + + this.sendOutLevelMessage(channelTypeIndex + 1, level) + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let level = 20 * Math.log((1.3 * outputLevel) / 0.775) + if (level < -90) { + level = -90 + } + // logger.debug(`Log level: ${level}`) + + this.sendOutLevelMessage(channelTypeIndex + 1, level) + } + + updatePflState(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + + if (state.faders[0].fader[channelIndex].pflOn === true) { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .mixerMessage, + channelTypeIndex + 1, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .value, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .type + ) + } else { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .mixerMessage, + channelTypeIndex + 1, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .value, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .type + ) + } + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + return true + } + + updateNextAux(channelIndex: number, level: number) { + return true + } + + updateInputGain(channelIndex: number, level: number) { + return true + } + updateInputSelector(channelIndex: number, inputSelected: number) { + return true + } + + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + return true + } + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + return true + } + + updateChannelName(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let channelName = state.faders[0].fader[channelIndex].label + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_NAME[0] + .mixerMessage, + channelTypeIndex + 1, + channelName, + 'string' + ) + } + + loadMixerPreset(presetName: string) {} + + injectCommand(command: string[]) { + return true + } +} diff --git a/server/src/utils/mixerConnections/StuderVistaMixerConnection.ts b/server/src/utils/mixerConnections/StuderVistaMixerConnection.ts new file mode 100644 index 00000000..7c98544e --- /dev/null +++ b/server/src/utils/mixerConnections/StuderVistaMixerConnection.ts @@ -0,0 +1,635 @@ +//@ts-ignore +import { BER } from 'node-emberplus' +import { store, state } from '../../reducers/store' +import net from 'net' + +//Utils: +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { logger } from '../logger' +import { storeSetMixerOnline } from '../../../../shared/src/actions/settingsActions' +import { + storeFaderLevel, + storeSetMute, + storeTogglePgm, +} from '../../../../shared/src/actions/faderActions' +import { + storeSetAuxLevel, + storeSetOutputLevel, +} from '../../../../shared/src/actions/channelActions' +import { remoteConnections } from '../../mainClasses' +import { IFader } from '../../../../shared/src/reducers/fadersReducer' +import { IChannel } from '../../../../shared/src/reducers/channelsReducer' + +export class StuderVistaMixerConnection { + mixerProtocol: IMixerProtocol + mixerIndex: number + deviceRoot: any + emberNodeObject: Array + mixerConnection: any + + constructor(mixerProtocol: IMixerProtocol, mixerIndex: number) { + this.sendOutMessage = this.sendOutMessage.bind(this) + this.pingMixerCommand = this.pingMixerCommand.bind(this) + + this.emberNodeObject = new Array(200) + this.mixerProtocol = mixerProtocol + this.mixerIndex = mixerIndex + + this.mixerOnline(false) + + logger.info('Setting up Ember connection') + + this.mixerConnection = net.createConnection( + { + port: parseInt( + state.settings[0].mixers[this.mixerIndex].devicePort + '' + ), + host: state.settings[0].mixers[this.mixerIndex].deviceIp, + timeout: 1000, + }, + () => {} + ) + + this.mixerConnection + .on('end', () => { + // When connection disconnected. + logger.info('Ember Client socket disconnect.') + this.mixerOnline(false) + }) + .on('error', (err: any) => { + logger.error(err) + this.mixerOnline(false) + }) + .on('connect', () => { + this.setupMixerConnection() + }) + } + + setupMixerConnection() { + logger.info('Ember connection established') + this.mixerConnection.on('data', (data: any) => { + let bufferString: string = '' + data.forEach((byte: any) => { + bufferString = bufferString + byte.toString(16) + ' ' + }) + bufferString.split('7f 8f').forEach((message: string) => { + message = '7f 8f' + message + // FADER LEVEL: + if ( + this.checkEmberCommand( + message, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_OUT_GAIN[0].mixerMessage + ) + ) { + this.handleEmberLevelCommand(message) + } else if ( + // AUX: + this.checkEmberCommand( + message, + this.mixerProtocol.channelTypes[0].fromMixer + .AUX_LEVEL[0].mixerMessage + ) + ) { + this.handleEmberAuxCommand(message) + } else if ( + // MUTE: + this.checkEmberCommand( + message, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_MUTE_ON[0].mixerMessage + ) + ) { + this.handleEmberMuteCommand(message) + } else { + logger.trace(`Unknown Vista message message: ${message}`) + } + }) + }) + + this.mixerOnline(true) + + //Ping OSC mixer if mixerProtocol needs it. + if (this.mixerProtocol.pingTime > 0) { + // Initial ping: + this.pingMixerCommand() + // Timer ping + let emberTimer = setInterval(() => { + this.pingMixerCommand() + }, this.mixerProtocol.pingTime) + } + } + + findChannelInArray(channelType: number, channelTypeIndex: number): number { + let channelArrayIndex = 0 + state.channels[0].chMixerConnection[this.mixerIndex].channel.forEach( + (channel: IChannel, index: number) => { + if ( + channel.channelType === channelType && + channel.channelTypeIndex === channelTypeIndex + ) { + channelArrayIndex = index + } + } + ) + return channelArrayIndex + } + + checkEmberCommand(message: string, protocolMessage: string): boolean { + let messageArray = message.split('31 ') + if (messageArray.length > 2) { + let protocolArray = protocolMessage.split(' ') + let isEqual = protocolArray.every( + (value: string, index: number) => { + if ( + value !== messageArray[index + 1]?.split(' ')[1] && + value !== '{channel}' && + value !== '{ch-type}' && + value !== '{aux}' + ) { + return false + } + return true + } + ) + return isEqual + } else { + return false + } + } + + handleEmberLevelCommand(message: string) { + // Extract Channel number and Channel Type (mono-st-51) + let { channelTypeIndex, channelType } = this.extractMessageIndex( + this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0] + .mixerMessage, + message + ) + + // Extract value: + let value = this.extractValue(message) + + //Invalid BER value received + if (value === -1) { + return + } + + // Update store: + let channelArrayIndex = this.findChannelInArray( + channelType, + channelTypeIndex + ) + let assignedFader = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelArrayIndex + ].assignedFader + + if ( + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelArrayIndex + ].fadeActive + ) { + return + } + + if ( + value > state.settings[0].autoResetLevel / 100 || + state.faders[0].fader[assignedFader].pgmOn || + state.faders[0].fader[assignedFader].voOn + ) { + store.dispatch(storeFaderLevel(assignedFader, value)) + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((item: { assignedFader: any }, index: number) => { + if (item.assignedFader === assignedFader) { + store.dispatch( + storeSetOutputLevel(this.mixerIndex, index, value) + ) + } + }) + if (!state.faders[0].fader[assignedFader].pgmOn) { + if (value > 0) { + store.dispatch(storeTogglePgm(assignedFader)) + } + } + global.mainThreadHandler.updatePartialStore(assignedFader) + remoteConnections.updateRemoteFaderState(assignedFader, value) + } + } + + handleEmberAuxCommand(message: string) { + // Extract Channel number, Aux and Type (mono-st-51) + let { channelTypeIndex, channelType, auxIndex } = + this.extractMessageIndex( + this.mixerProtocol.channelTypes[0].fromMixer.AUX_LEVEL[0] + .mixerMessage, + message + ) + + // Extract value: + let value = this.extractValue(message) + + //Invalid BER value received + if (value === -1) { + return + } + + // Update store: + let channelArrayIndex = this.findChannelInArray( + channelType, + channelTypeIndex + ) + + store.dispatch( + storeSetAuxLevel( + this.mixerIndex, + channelArrayIndex, + auxIndex, + value + ) + ) + + global.mainThreadHandler.updateFullClientStore() + remoteConnections.updateRemoteAuxPanels() + } + + handleEmberMuteCommand(message: string) { + // Extract Channel number and Channel Type (mono-st-51) + let { channelTypeIndex, channelType } = this.extractMessageIndex( + this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_MUTE_ON[0] + .mixerMessage, + message + ) + + // Extract Mute state: + let messageArray = message.split('31 ') + let mute = + parseInt(messageArray[messageArray.length - 1].split(' ')[5]) === 1 + ? true + : false + + // Update store: + let assignedFader = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + this.findChannelInArray(channelType, channelTypeIndex) + ].assignedFader + + store.dispatch(storeSetMute(assignedFader, mute)) + global.mainThreadHandler.updatePartialStore(assignedFader) + } + + extractMessageIndex( + protocolMessage: string, + message: string + ): { channelTypeIndex: number; channelType: number; auxIndex: number } { + let messageArray = message.split('31 ') + let protocolArray = protocolMessage.split(' ') + let channelTypeIndex: number = 0 + let channelType: number = 0 + let auxIndex: number = 0 + + // Extract Channel number, Aux and Type (mono-st-51) + protocolArray.forEach((value: string, index: number) => { + if (value === '{channel}') { + channelTypeIndex = + parseInt(messageArray[index + 1].split(' ')[1], 16) - + 160 - + 1 + } else if (value === '{ch-type}') { + channelType = + parseInt(messageArray[index + 1].split(' ')[1], 16) - + 160 - + 1 + } else if (value === '{aux}') { + auxIndex = + parseInt(messageArray[index + 1].split(' ')[1], 16) - + 160 - + 1 + } + }) + return { + channelTypeIndex: channelTypeIndex, + channelType: channelType, + auxIndex: auxIndex, + } + } + + extractValue(message: string): number { + let messageArray = message.split('31 ') + let hexString = messageArray[messageArray.length - 1] + + // Workaround - Sometimes Studer sends a fader without valid value + if (hexString.length < 14) { + return -1 + } + let hexVal = hexString.split(' ').slice(3) + // second byte tells the length of value + hexVal = hexVal.slice(0, parseInt(hexVal[1], 16) + 2) + let BERreader = new BER.Reader( + Buffer.from( + hexVal.map((byte: string) => { + return parseInt(byte, 16) + }) + ) + ) + let value = Math.exp(BERreader.readReal() / 40) / 1.2954 + if (value < 0.09) { + value = 0 + } + return value + } + + mixerOnline(onLineState: boolean) { + store.dispatch(storeSetMixerOnline(this.mixerIndex, onLineState)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex) + } + + pingMixerCommand() { + this.mixerProtocol.pingCommand.map((command) => { + if (command.mixerMessage.includes('{channel}')) { + this.pingChannel(command.mixerMessage) + } else { + let hexArray = command.mixerMessage.split(' ') + let buf = Buffer.from( + hexArray.map((val: string) => { + return parseInt(val, 16) + }) + ) + this.mixerConnection.write(buf) + } + logger.trace('WRITING PING TO MIXER') + }) + } + + pingChannel(mixerMessage: string) { + state.faders[0].fader.forEach((fader: IFader, index: number) => { + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((channel: IChannel) => { + if (channel.assignedFader === index) { + let message = mixerMessage + .replace( + '{ch-type}', + (channel.channelType + 1 + 160).toString(16) + ) + .replace( + '{channel}', + (channel.channelTypeIndex + 1 + 160).toString(16) + ) + if (message.includes('{aux}')) { + this.pingAuxSend(message) + } else { + let hexArray = message.split(' ') + let buf = Buffer.from( + hexArray.map((val: string) => { + return parseInt(val, 16) + }) + ) + // logger.debug(`Pinging: ${buf}`) + this.mixerConnection.write(buf) + } + } + }) + }) + } + + pingAuxSend(message: string) { + for ( + let index = 0; + index < state.settings[0].mixers[this.mixerIndex].numberOfAux; + index++ + ) { + let auxMessage = message.replace( + '{aux}', + (index + 1 + 160).toString(16) + ) + let hexArray = auxMessage.split(' ') + let buf = Buffer.from( + hexArray.map((val: string) => { + return parseInt(val, 16) + }) + ) + // logger.debug(`Pinging: ${buf}`) + this.mixerConnection.write(buf) + } + } + + sendOutMessage( + mixerMessage: string, + channel: number, + value: string | number + ) { + let channelVal: number + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channel - 1 + ].channelTypeIndex + + channelVal = 160 + channelTypeIndex + 1 + + let channelByte = new Uint8Array([channelVal & 0x000000ff]) + + let BERwriter = new BER.Writer() + if (typeof value === 'number') { + BERwriter.startSequence() + BERwriter.writeReal(Math.floor(value)) + BERwriter.endSequence() + } else { + BERwriter.startSequence() + BERwriter.writeString(value) + BERwriter.endSequence() + } + + let bufferString: string = '' + BERwriter.buffer.forEach((element: any) => { + bufferString += ('0' + element.toString(16)).slice(-2) + ' ' + }) + mixerMessage = mixerMessage.replace( + '{channel}', + ('0' + channelByte[0].toString(16)).slice(-2) + ) + mixerMessage = mixerMessage.replace( + '{argument}', + (bufferString + '00 00 00 00 00').slice(3, 35) + ) + + let hexArray = mixerMessage.split(' ') + let buf = Buffer.from( + hexArray.map((val: string) => { + return parseInt(val, 16) + }) + ) + this.mixerConnection.write(buf) + logger.trace(`Send HEX: ${mixerMessage}`) + } + + sendOutLevelMessage(channel: number, value: number) { + let levelMessage: string + let channelVal: number + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channel - 1 + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channel - 1 + ].channelTypeIndex + + levelMessage = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage + channelVal = 160 + channelTypeIndex + 1 + + let channelByte = new Uint8Array([channelVal & 0x000000ff]) + + logger.trace(`Fader value: ${Math.floor(value)}`) + let BERwriter = new BER.Writer() + + BERwriter.startSequence() + BERwriter.writeReal(Math.floor(value)) + BERwriter.endSequence() + + let bufferString: string = '' + BERwriter.buffer.forEach((element: any) => { + bufferString += ('0' + element.toString(16)).slice(-2) + ' ' + }) + levelMessage = levelMessage.replace( + '{channel}', + ('0' + channelByte[0].toString(16)).slice(-2) + ) + levelMessage = levelMessage.replace( + '{level}', + (bufferString + '00 00 00 00 00').slice(3, 35) + ) + + let hexArray = levelMessage.split(' ') + let buf = Buffer.from( + hexArray.map((val: string) => { + return parseInt(val, 16) + }) + ) + this.mixerConnection.write(buf) + logger.trace(`Send HEX: ${levelMessage}`) + } + + sendOutRequest(mixerMessage: string, channel: number) { + return + } + + updateOutLevel(channelIndex: number) { + let outputlevel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].outputLevel + let level = 40 * Math.log(1.295 * outputlevel) + if (level < -90) { + level = -90 + } + // logger.debug(`Log level: ${level}`) + + this.sendOutLevelMessage(channelIndex + 1, level) + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + let level = 40 * Math.log(1.295 * outputLevel) + if (level < -90) { + level = -90 + } + // logger.debug(`Log level: ${level}`) + + this.sendOutLevelMessage(channelIndex + 1, level) + } + + updatePflState(channelIndex: number) { + return + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + if (muteOn === true) { + let mute = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_ON[0] + this.sendOutMessage( + mute.mixerMessage, + channelTypeIndex + 1, + mute.value + ) + } else { + let mute = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_OFF[0] + this.sendOutMessage( + mute.mixerMessage, + channelTypeIndex + 1, + mute.value + ) + } + } + + updateNextAux(channelIndex: number, level: number) { + this.updateAuxLevel( + channelIndex, + state.settings[0].mixers[this.mixerIndex].nextSendAux - 1, + level + ) + } + + updateInputGain(channelIndex: number, level: number) { + return true + } + updateInputSelector(channelIndex: number, inputSelected: number) { + return true + } + + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + return true + } + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + 1 + let auxSendCmd = + this.mixerProtocol.channelTypes[channelType].toMixer.AUX_LEVEL[0] + let auxSendNumber = 160 + auxSendIndex + 1 + + let auxByte = new Uint8Array([auxSendNumber & 0x000000ff]) + let message = auxSendCmd.mixerMessage.replace( + '{aux}', + ('0' + auxByte[0].toString(16)).slice(-2) + ) + + level = 40 * Math.log(1.295 * level) + if (level < -80) { + level = -90 + } + //level = level * (auxSendCmd.max - auxSendCmd.min) + auxSendCmd.min + + this.sendOutMessage(message, channel, level) + } + + updateChannelName(channelIndex: number) { + return + } + + loadMixerPreset(presetName: string) {} + + injectCommand(command: string[]) { + return true + } +} diff --git a/server/src/utils/mixerConnections/VMixMixerConnection.ts b/server/src/utils/mixerConnections/VMixMixerConnection.ts new file mode 100644 index 00000000..f26463ef --- /dev/null +++ b/server/src/utils/mixerConnections/VMixMixerConnection.ts @@ -0,0 +1,682 @@ +//Node Modules: +import { store, state } from '../../reducers/store' +import { ConnectionTCP } from 'node-vmix' +import { XmlApi } from 'vmix-js-utils' + +//Utils: +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { SET_OUTPUT_LEVEL } from '../../../../shared/src/actions/channelActions' +import { + storeFaderLevel, + storeFaderFx, + storeSetMute, + storeInputGain, + storeSetPfl, + storeSetPgm, + storeSetVo, +} from '../../../../shared/src/actions/faderActions' +import { storeSetMixerOnline } from '../../../../shared/src/actions/settingsActions' +import { logger } from '../logger' +import { sendVuLevel } from '../vuServer' +import { VuType } from '../../../../shared/src/utils/vu-server-types' +import { dbToFloat } from './LawoRubyConnection' + +export class VMixMixerConnection { + mixerProtocol: IMixerProtocol + mixerIndex: number + cmdChannelIndex: number + vmixConnection: any + vmixVuConnection: ConnectionTCP + mixerOnlineTimer: any + + constructor(mixerProtocol: IMixerProtocol, mixerIndex: number) { + this.sendOutMessage = this.sendOutMessage.bind(this) + this.pingMixerCommand = this.pingMixerCommand.bind(this) + + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + + this.mixerProtocol = mixerProtocol + this.mixerIndex = mixerIndex + //If default store has been recreated multiple mixers are not created + if (!state.channels[0].chMixerConnection[this.mixerIndex]) { + state.channels[0].chMixerConnection[this.mixerIndex] = { + channel: [], + } + } + + this.cmdChannelIndex = + this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage + .split('/') + .findIndex((ch) => ch === '{channel}') + + this.vmixConnection = new ConnectionTCP( + state.settings[0].mixers[this.mixerIndex].deviceIp, + { + port: parseInt( + state.settings[0].mixers[this.mixerIndex].devicePort + '' + ), + } + ) + this.vmixVuConnection = new ConnectionTCP( + state.settings[0].mixers[this.mixerIndex].deviceIp, + { + port: parseInt( + state.settings[0].mixers[this.mixerIndex].devicePort + '' + ), + } + ) + this.setupMixerConnection() + } + + mixerOnline(onLineState: boolean) { + store.dispatch(storeSetMixerOnline(this.mixerIndex, onLineState)) + global.mainThreadHandler.updateMixerOnline(this.mixerIndex, onLineState) + } + + setupMixerConnection() { + this.vmixConnection._socket + .on('connect', () => { + logger.info('Receiving state of desk') + this.initialCommands() + + this.mixerOnline(true) + global.mainThreadHandler.updateFullClientStore() + }) + .on('data', (data: any) => { + const message = data.toString() + // logger.trace(XmlApi.DataParser.parse(message)) + clearTimeout(this.mixerOnlineTimer) + if (!state.settings[0].mixers[this.mixerIndex].mixerOnline) { + this.mixerOnline(true) + } + }) + .on('error', (error: any) => { + global.mainThreadHandler.updateFullClientStore() + logger.error(error) + }) + .on('disconnect', () => { + this.mixerOnline(false) + logger.info('Lost VMix connection') + }) + + logger.info( + `OSC listening on port ${ + state.settings[0].mixers[this.mixerIndex].localOscPort + }` + ) + + //Ping OSC mixer if mixerProtocol needs it. + if (this.mixerProtocol.pingTime > 0) { + setInterval(() => { + this.pingMixerCommand() + }, this.mixerProtocol.pingTime) + } + + // use separate connection for updates to prevent blocking any commands + this.vmixVuConnection.on('xml', (xml: string) => { + const doc = XmlApi.DataParser.parse(xml) + const inputs = XmlApi.Inputs.extractInputsFromXML(doc) + + const mappedInputs = inputs.map((input) => { + const d: Record = { + name: input.childNodes[0].nodeValue, + } + + const attrs = [ + 'volume', + 'muted', + 'meterF1', + 'meterF2', + 'number', + 'gainDb', + 'solo', + ] + Object.values(input.attributes) + .filter((attr: Attr) => attrs.includes(attr.name)) + .forEach((attr: Attr) => { + d[attr.name] = attr.value + }) + + d.volume = Math.pow(parseFloat(d.volume || '0') / 100, 0.25) + d.meterF1 = (9.555 * Math.log(d.meterF1 || 0)) / Math.log(3) + d.meterF2 = (9.555 * Math.log(d.meterF2 || 0)) / Math.log(3) + d.muted = d.muted ? d.muted === 'True' : true + d.solo = d.solo === 'True' + d.gainDb = parseFloat(d.gainDb || '0') / 24 + + return d + }) + + mappedInputs.forEach((input) => { + if ('number' in input) { + sendVuLevel( + input.number - 1, + VuType.Channel, + 0, + dbToFloat(input.meterF1 + 12) + ) // add +15 to convert from dBFS + sendVuLevel( + input.number - 1, + VuType.Channel, + 1, + dbToFloat(input.meterF2 + 12) + ) // add +15 to convert from dBFS + } + + // If vMix has more channels than Sisyfos is configured to handle, + // then do nothing with those additional channels. + if (!this.doesChannelExists(input.number - 1)) { + return + } + + const { outputLevel, fadeActive, assignedFader } = + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[input.number - 1] + const { inputGain, muteOn, pflOn, pgmOn, voOn } = + state.faders[0].fader[assignedFader] + let sendUpdate = false + const dispatch = (update: any) => { + store.dispatch(update) + sendUpdate = true + } + + if ('muted' in input) { + if (input.muted === false) { + if ( + !fadeActive && + outputLevel > 0 && + Math.abs(outputLevel - input.volume) > 0.01 + ) { + dispatch( + storeFaderLevel(assignedFader, input.volume) + ) + store.dispatch({ + type: SET_OUTPUT_LEVEL, + channel: assignedFader, + mixerIndex: this.mixerIndex, + level: voOn + ? input.volume / + (state.settings[0].voLevel / 100) + : input.volume, + }) + } + if (muteOn) { + dispatch(storeSetMute(assignedFader, false)) + } + if (!fadeActive && !pgmOn && !voOn) { + dispatch(storeSetPgm(assignedFader, true)) + store.dispatch({ + type: SET_OUTPUT_LEVEL, + channel: assignedFader, + mixerIndex: this.mixerIndex, + level: input.volume, + }) + } + } else if (!muteOn) { + if (pgmOn) { + dispatch(storeSetPgm(assignedFader, false)) + } + if (voOn) { + dispatch(storeSetVo(assignedFader, false)) + } + } + + if (inputGain !== input.gainDb) { + dispatch(storeInputGain(assignedFader, input.gainDb)) + } + if (pflOn !== input.solo) { + dispatch(storeSetPfl(assignedFader, input.solo)) + } + } + + if (sendUpdate) { + global.mainThreadHandler.updatePartialStore( + input.number - 1 + ) + } + }) + }) + this.vmixVuConnection.on('connect', () => { + setInterval(() => { + this.vmixVuConnection.send('XML') + }, 80) + }) + } + + initialCommands() { + this.vmixConnection.send('XML') + this.vmixConnection.send({ Function: 'SUBSCRIBE TALLY' }) + return + // To prevent network overload, timers will delay the requests. + this.mixerProtocol.initializeCommands?.forEach( + (item, itemIndex: number) => { + setTimeout(() => { + if (item.mixerMessage.includes('{channel}')) { + if (item.type !== undefined && item.type === 'aux') { + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((channel: any) => { + channel.auxLevel.forEach( + (auxLevel: any, auxIndex: number) => { + if (channel.assignedFader >= 0) { + if ( + state.faders[0].fader[ + channel.assignedFader + ] + ) { + setTimeout(() => { + this.sendOutRequestAux( + item.mixerMessage, + auxIndex + 1, + state.faders[0].fader[ + channel + .assignedFader + ].monitor + ) + }, state.faders[0].fader[channel.assignedFader].monitor * 10 + auxIndex * 100) + } + } + } + ) + }) + } else { + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((channel: any, index: any) => { + this.sendOutRequest( + item.mixerMessage, + index + 1 + ) + }) + } + } else { + let value = item.value || 0 + let type = item.type || 'i' + this.sendOutMessage(item.mixerMessage, 1, value, type) + } + }, itemIndex * 100) + } + ) + } + + pingMixerCommand() { + //Ping OSC mixer if mixerProtocol needs it. + if (!this.mixerProtocol.pingCommand.length) return + + this.mixerProtocol.pingCommand.map((command) => { + let value = command.value || 0 + let type = command.type || 'i' + this.sendOutMessage(command.mixerMessage, 0, value, type) + }) + global.mainThreadHandler.updateFullClientStore() + this.mixerOnlineTimer = setTimeout(() => { + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + }, this.mixerProtocol.pingTime) + } + + checkFxCommands(message: any) { + Object.keys(fxParamsList).forEach((keyName: string) => { + if (!isNaN(parseFloat(keyName))) { + return + } + + let fxKey = keyName as keyof typeof fxParamsList + if ( + this.mixerProtocol.channelTypes[0].fromMixer[ + fxParamsList[fxKey] + ] && + this.checkVMixCommand( + message.address, + this.mixerProtocol.channelTypes[0].fromMixer[ + fxParamsList[fxKey] + ][0].mixerMessage + ) + ) { + let ch = message.address.split('/')[this.cmdChannelIndex] + store.dispatch( + storeFaderFx( + fxParamsList[fxKey], + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader, + message.args[0] + ) + ) + global.mainThreadHandler.updatePartialStore( + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader + ) + } + + logger.trace(fxKey) + }) + } + + checkVMixCommand(message: string, command: string | undefined): boolean { + if (!command) return false + if (message === command) return true + return + let messageArray: string[] = message.split('/') + let commandArray: string[] = command.split('/') + let status: boolean = true + if (messageArray.length !== commandArray.length) { + return false + } + commandArray.forEach((commandPart: string, index: number) => { + if (commandPart === '{channel}') { + if (typeof parseFloat(messageArray[index]) !== 'number') { + status = false + } + } else if (commandPart === '{argument}') { + if (typeof parseFloat(messageArray[index]) !== 'number') { + status = false + } + } else if (commandPart !== messageArray[index]) { + status = false + } + }) + return status + } + + sendOutMessage( + vMixMessage: string, + channel: number, + value: string | number, + type: string + ) { + if (state.settings[0].mixers[this.mixerIndex].mixerOnline) { + logger.trace(`send${vMixMessage} Input=1&Value=${value}`) + this.vmixConnection.send({ + Function: vMixMessage, + Input: channel, // todo - should we map these? + Value: value, + }) + } + } + + sendOutRequest(oscMessage: string, channel: number) { + let channelString = this.mixerProtocol.leadingZeros + ? ('0' + channel).slice(-2) + : channel.toString() + let message = oscMessage.replace('{channel}', channelString) + if (message != 'none') { + this.vmixConnection.send({ + address: message, + }) + } + } + + sendOutRequestAux(oscMessage: string, channel: number, auxSend: number) { + let channelString = this.mixerProtocol.leadingZeros + ? ('0' + channel).slice(-2) + : channel.toString() + let message = oscMessage.replace('{channel}', channelString) + let auxSendNumber = this.mixerProtocol.leadingZeros + ? ('0' + String(auxSend)).slice(-2) + : String(auxSend) + message = message.replace('{argument}', auxSendNumber) + logger.trace(`Initial Aux Message : ${message}`) + if (message != 'none') { + this.vmixConnection.send({ + address: message, + }) + } + } + + updateOutLevel(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + const level = Math.round( + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].outputLevel * 100 + ) + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage, + channelTypeIndex + 1, + level, + 'f' + ) + } + + updatePflState(channelIndex: number) { + let { channelType, channelTypeIndex, outputLevel } = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + + if (state.faders[0].fader[channelIndex].pflOn === true) { + if (outputLevel === 0) { + // this.sendOutMessage('AudioOff', channelTypeIndex + 1, 1, '') + // this.sendOutMessage('SetVolume', channelTypeIndex + 1, 75, '') + } + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .mixerMessage, + channelTypeIndex + 1, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .value, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .type + ) + } else { + if (outputLevel === 0) { + // this.sendOutMessage('SetVolume', channelTypeIndex + 1, 0, '') + // this.sendOutMessage('AudioOn', channelTypeIndex + 1, 1, '') + } + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .mixerMessage, + channelTypeIndex + 1, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .value, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .type + ) + } + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + const { channelType, channelTypeIndex, outputLevel } = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + + if (muteOn === true && outputLevel > 0) { + let mute = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_ON[0] + this.sendOutMessage( + mute.mixerMessage, + channelTypeIndex + 1, + mute.value, + mute.type + ) + } else if (muteOn === false && outputLevel > 0) { + let mute = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_OFF[0] + this.sendOutMessage( + mute.mixerMessage, + channelTypeIndex + 1, + mute.value, + mute.type + ) + } + } + + updateNextAux(channelIndex: number, level: number) { + this.updateAuxLevel( + channelIndex, + state.settings[0].mixers[this.mixerIndex].nextSendAux - 1, + level + ) + } + + updateInputGain(channelIndex: number, level: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let mixerMessage = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_INPUT_GAIN[0] + if (mixerMessage.min !== undefined && mixerMessage.max !== undefined) { + level = + mixerMessage.min + (mixerMessage.max - mixerMessage.min) * level + } + this.sendOutMessage( + mixerMessage.mixerMessage, + channelTypeIndex + 1, + Math.round(level), + 'f' + ) + } + updateInputSelector(channelIndex: number, inputSelected: number) { + const { channelType, channelTypeIndex } = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + let { mixerMessage, value } = + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_INPUT_SELECTOR[inputSelected - 1] + + this.sendOutMessage(mixerMessage, channelTypeIndex + 1, value, '') + } + + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let fx = + this.mixerProtocol.channelTypes[channelType].toMixer[fxParam][0] + if (fx.min !== undefined && fx.max !== undefined) { + level = fx.min + (fx.max - fx.min) * level + } + this.sendOutMessage( + fx.mixerMessage, + channelTypeIndex + 1, + Math.round(level), + 'f' + ) // todo - is it always rounded? + } + + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channel = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + 1 + let auxSendCmd = + this.mixerProtocol.channelTypes[channelType].toMixer.AUX_LEVEL[0] + let auxSendNumber = this.mixerProtocol.leadingZeros + ? ('0' + String(auxSendIndex + 1)).slice(-2) + : String(auxSendIndex + 1) + let message = auxSendCmd.mixerMessage.replace( + '{argument}', + auxSendNumber + ) + + this.sendOutMessage(message, channel, level, 'f') + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + let { channelType, channelTypeIndex } = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ] + let { muteOn } = state.faders[0].fader[channelIndex] + outputLevel = Math.round(100 * outputLevel) + + if (!muteOn && outputLevel > 0) { + this.sendOutMessage('AudioOn', channelTypeIndex + 1, 1, '') + } + + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage, + channelTypeIndex + 1, + String(outputLevel), + 'f' + ) + + if (outputLevel <= 1) { + this.sendOutMessage('AudioOff', channelTypeIndex + 1, 1, '') + this.sendOutMessage('SetVolume', channelTypeIndex + 1, 75, '') + } + } + + updateChannelName(channelIndex: number) { + // let channelType = + // state.channels[0].chMixerConnection[this.mixerIndex].channel[ + // channelIndex + // ].channelType + // let channelTypeIndex = + // state.channels[0].chMixerConnection[this.mixerIndex].channel[ + // channelIndex + // ].channelTypeIndex + // let channelName = state.faders[0].fader[channelIndex].label + // this.sendOutMessage( + // this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_NAME[0] + // .mixerMessage, + // channelTypeIndex + 1, + // channelName, + // 's' + // ) + return true + } + + loadMixerPreset(presetName: string) { + logger.info(`Loading preset : ${presetName}`) + if (this.mixerProtocol.presetFileExtension === 'X32') { + let data = JSON.parse( + '{}' // ''fs.readFileSync(path.resolve(process.cwd(), 'storage', presetName)) + ) + + this.vmixConnection.send({ + address: this.mixerProtocol.loadPresetCommand[0].mixerMessage, + args: [ + { + type: 's', + value: 'scene', + }, + { + type: 'i', + value: parseInt(data.sceneIndex), + }, + ], + }) + } + } + + injectCommand(command: string[]) { + return true + } + + doesChannelExists(channelNumber: number): boolean { + return !!state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelNumber + ] + } +} diff --git a/server/src/utils/mixerConnections/YamahaQlClConnection.ts b/server/src/utils/mixerConnections/YamahaQlClConnection.ts new file mode 100644 index 00000000..f149d467 --- /dev/null +++ b/server/src/utils/mixerConnections/YamahaQlClConnection.ts @@ -0,0 +1,459 @@ +//Node Modules: +import net from 'net' +import { store, state } from '../../reducers/store' +import { remoteConnections } from '../../mainClasses' + +//Utils: +import { + fxParamsList, + IMixerProtocol, +} from '../../../../shared/src/constants/MixerProtocolInterface' +import { storeSetOutputLevel } from '../../../../shared/src/actions/channelActions' +import { + storeFaderLevel, + storeTogglePgm, + storeSetMute, +} from '../../../../shared/src/actions/faderActions' +import { logger } from '../logger' +import { storeSetMixerOnline } from '../../../../shared/src/actions/settingsActions' +import { sendVuLevel } from '../vuServer' +import { VuType } from '../../../../shared/src/utils/vu-server-types' + +export class QlClMixerConnection { + mixerProtocol: IMixerProtocol + mixerIndex: number + cmdChannelIndex: number + midiConnection: any + mixerOnlineTimer: any + + constructor(mixerProtocol: IMixerProtocol, mixerIndex: number) { + this.sendOutMessage = this.sendOutMessage.bind(this) + this.pingMixerCommand = this.pingMixerCommand.bind(this) + + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + + this.mixerProtocol = mixerProtocol + this.mixerIndex = mixerIndex + + this.cmdChannelIndex = + this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage + .split('/') + .findIndex((ch) => ch === '{channel}') + + this.midiConnection = new net.Socket() + this.midiConnection.connect( + 50000, + state.settings[0].mixers[this.mixerIndex].deviceIp, + () => { + logger.info('Connected to Yamaha mixer') + } + ) + this.setupMixerConnection() + } + + setupMixerConnection() { + this.midiConnection + .on('ready', () => { + logger.info('Receiving state of desk') + this.mixerProtocol.initializeCommands.forEach((item) => { + if (item.mixerMessage.includes('{channel}')) { + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((channel: any, index: any) => { + this.sendOutMessage( + item.mixerMessage, + index + 1, + 0, + '' + ) + }) + } else { + this.sendOutMessage( + item.mixerMessage, + 0, + item.value, + item.type + ) + } + }) + global.mainThreadHandler.updateFullClientStore() + }) + .on('data', (data: any) => { + clearTimeout(this.mixerOnlineTimer) + store.dispatch(storeSetMixerOnline(this.mixerIndex, true)) + + let buffers = [] + let lastIndex = 0 + for (let index = 1; index < data.length; index++) { + if (data[index] === 240) { + buffers.push(data.slice(lastIndex, index)) + lastIndex = index + } + } + if (buffers.length === 0) { + buffers.push(data) + } + + buffers.forEach((message) => { + logger.trace( + `Received Midi Message : ${message.toString('hex')}` + ) + if ( + this.checkMidiCommand( + message, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_VU[0].mixerMessage + ) + ) { + let mixerValues: string[] = message.split(' ') + let ch = parseInt(mixerValues[3]) + let assignedFader = + 1 + + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader + let mixerValue = parseInt(mixerValues[6]) + sendVuLevel( + assignedFader, + VuType.Channel, + 0, + mixerValue + ) + } else if ( + this.checkMidiCommand( + message, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_OUT_GAIN[0].mixerMessage + ) + ) { + let ch = 1 + (message[11] | (message[10] << 8)) + let assignedFader = + 1 + + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[ch - 1].assignedFader + let mixerLevel: number = + message[16] | (message[15] << 8) // parseFloat(message[16]) + let faderLevel = Math.pow(2, mixerLevel / 1920) - 1 + //let faderLevel = Math.log10((mixerLevel + 32768) / (1000 + 32768)) + if ( + !state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel[ch - 1].fadeActive && + faderLevel > this.mixerProtocol.fader.min + ) { + store.dispatch( + storeFaderLevel(assignedFader - 1, faderLevel) + ) + if ( + !state.faders[0].fader[assignedFader - 1].pgmOn + ) { + store.dispatch( + storeTogglePgm(assignedFader - 1) + ) + } + + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + assignedFader - 1, + faderLevel + ) + } + if ( + state.faders[0].fader[assignedFader - 1].pgmOn + ) { + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach( + (channel: any, index: number) => { + if ( + channel.assignedFader === + assignedFader - 1 + ) { + this.updateOutLevel(index) + } + } + ) + } + } + global.mainThreadHandler.updatePartialStore( + assignedFader - 1 + ) + } else if ( + this.checkMidiCommand( + message, + this.mixerProtocol.channelTypes[0].fromMixer + .CHANNEL_MUTE_ON[0].mixerMessage + ) + ) { + // MUTE ON/OFF COMMAND + let channelIndex = message[11] | (message[10] << 8) + + let value: boolean = message[16] === 0 ? true : false + logger.trace( + `Receive Buffer Channel On/off - Channel ${ + channelIndex + 1 + } Val :${message[16]}` + ) + + let assignedFaderIndex = + state.channels[0].chMixerConnection[this.mixerIndex] + .channel[channelIndex].assignedFader + + store.dispatch(storeSetMute(assignedFaderIndex, value)) + + if (remoteConnections) { + remoteConnections.updateRemoteFaderState( + assignedFaderIndex, + value ? 1 : 0 + ) + } + state.channels[0].chMixerConnection[ + this.mixerIndex + ].channel.forEach((channel: any, index: number) => { + if ( + channel.assignedFader === assignedFaderIndex && + index !== channelIndex + ) { + this.updateMuteState( + index, + state.faders[0].fader[assignedFaderIndex] + .muteOn + ) + } + }) + global.mainThreadHandler.updatePartialStore( + assignedFaderIndex + ) + } + }) + }) + .on('error', (error: any) => { + logger.data(error).error('Lost QlCl connection') + }) + + //Ping OSC mixer if mixerProtocol needs it. + if (this.mixerProtocol.pingTime > 0) { + let oscTimer = setInterval(() => { + this.pingMixerCommand() + }, this.mixerProtocol.pingTime) + } + } + + pingMixerCommand() { + this.mixerOnlineTimer = setTimeout(() => { + store.dispatch(storeSetMixerOnline(this.mixerIndex, false)) + }, this.mixerProtocol.pingTime) + } + + checkMidiCommand(midiMessage: number[], command: string) { + if (!midiMessage) return false + let commandArray = command.split(' ') + let valid = true + for (let i = 0; i <= 8; i++) { + if (i < midiMessage.length) { + if ( + ('0' + midiMessage[i].toString(16)).substr(-2) !== + commandArray[i] + ) { + valid = false + } + } else { + valid = false + } + } + return valid + } + + sendOutMessage( + message: string, + channel: number, + value: string | number, + type: string + ) { + let valueNumber: number + if (typeof value === 'string') { + value = parseFloat(value) + } + + valueNumber = value * 2048 + let valueByte = new Uint8Array([ + (valueNumber & 0xff00) >> 8, + valueNumber & 0x00ff, + ]) + + let channelByte = new Uint8Array([ + (channel & 0xff00) >> 8, + channel & 0x00ff, + ]) + + let command = message.replace( + '{channel}', + channelByte[0].toString(16) + ' ' + channelByte[1].toString(16) + ) + command = command.replace( + '{level}', + valueByte[0].toString(16) + ' ' + valueByte[1].toString(16) + ) + let a = command.split(' ') + let buf = Buffer.from( + a.map((val: string) => { + return parseInt(val, 16) + }) + ) + logger.trace(`Sending Command :${command}`) + this.midiConnection.write(buf) + } + + updateOutLevel(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let faderIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].assignedFader + if (state.faders[0].fader[faderIndex].pgmOn) { + store.dispatch( + storeSetOutputLevel( + this.mixerIndex, + channelIndex, + state.faders[0].fader[faderIndex].faderLevel + ) + ) + } + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage, + channelTypeIndex, + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].outputLevel, + 'f' + ) + } + + updatePflState(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + if (state.faders[0].fader[channelIndex].pflOn === true) { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .mixerMessage, + channelTypeIndex, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .value, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0] + .type + ) + } else { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .mixerMessage, + channelTypeIndex, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .value, + this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0] + .type + ) + } + } + + updateMuteState(channelIndex: number, muteOn: boolean) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + if (muteOn === true) { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_ON[0].mixerMessage, + channelTypeIndex, + '', + '' + ) + } else { + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_MUTE_OFF[0].mixerMessage, + channelTypeIndex, + '', + '' + ) + } + } + + updateNextAux(channelIndex: number, level: number) { + return true + } + + updateInputGain(channelIndex: number, level: number) { + return true + } + updateInputSelector(channelIndex: number, inputSelected: number) { + return true + } + + updateFx(fxParam: fxParamsList, channelIndex: number, level: number) { + return true + } + updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { + return true + } + + updateFadeIOLevel(channelIndex: number, outputLevel: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer + .CHANNEL_OUT_GAIN[0].mixerMessage, + channelTypeIndex, + String(outputLevel), + 'f' + ) + } + + updateChannelName(channelIndex: number) { + let channelType = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelType + let channelTypeIndex = + state.channels[0].chMixerConnection[this.mixerIndex].channel[ + channelIndex + ].channelTypeIndex + let channelName = state.faders[0].fader[channelIndex].label + this.sendOutMessage( + this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_NAME[0] + .mixerMessage, + channelTypeIndex, + channelName, + 's' + ) + } + + loadMixerPreset(presetName: string) {} + + injectCommand(command: string[]) { + return true + } +} diff --git a/server/src/utils/mixerConnections/productSpecific/behringerXr.ts b/server/src/utils/mixerConnections/productSpecific/behringerXr.ts new file mode 100644 index 00000000..d638cd50 --- /dev/null +++ b/server/src/utils/mixerConnections/productSpecific/behringerXr.ts @@ -0,0 +1,41 @@ +import { state } from '../../../reducers/store' +import { sendVuLevel } from '../../vuServer' +import { VuType } from '../../../../../shared/src/utils/vu-server-types' + +const DATA_OFFSET = 4 + +export const behringerXrMeter = (mixerIndex: number, message: any) => { + //Test data from Behringer: + //message = [40, 0, 0, 0, 133, 157, 183, 156, 72, 154, 101, 157, 229, 162, 241, 158, 253, 162, 156, 162, 131, 162, 253, 162, 81, 162, 29, 162, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 223, 157, 223, 157, 223, 157, 223, 157]; + + let uint8bytes = Uint8Array.from(message[0]) + let dataview = new DataView(uint8bytes.buffer) + + for ( + let i = 0; + i < state.settings[0].mixers[0].numberOfChannelsInType[0]; + i++ + ) { + let level = (dataview.getInt16(DATA_OFFSET + 2 * i, true) + 8000) / 8000 + sendVuLevel(i, VuType.Channel, 0, level) + } +} + +export const behringerReductionMeter = (mixerIndex: number, message: any) => { + //Test data from Behringer: + //message = + + let uint8bytes = Uint8Array.from(message[0]) + let dataview = new DataView(uint8bytes.buffer) + + for ( + let i = 0; + i < state.settings[0].mixers[0].numberOfChannelsInType[0]; + i++ + ) { + let level = + 1 - + (dataview.getInt16(DATA_OFFSET + 2 * (i + 16), true) + 8000) / 8000 + sendVuLevel(i, VuType.Reduction, 0, level) + } +} diff --git a/server/src/utils/mixerConnections/productSpecific/midas.ts b/server/src/utils/mixerConnections/productSpecific/midas.ts new file mode 100644 index 00000000..f47ab6da --- /dev/null +++ b/server/src/utils/mixerConnections/productSpecific/midas.ts @@ -0,0 +1,45 @@ +import { state } from '../../../reducers/store' +import { sendVuLevel } from '../../vuServer' +import { VuType } from '../../../../../shared/src/utils/vu-server-types' + +const calcVuLevel = (level: number) => { + return Math.log(level) / Math.log(600) + 1 +} + +export const midasMeter = (mixerIndex: number, message: any) => { + const DATA_OFFSET = 4 + let uint8bytes = Uint8Array.from(message[0]) + let dataview = new DataView(uint8bytes.buffer) + let level: number + let reductionLevel: number + let assignedFader: number + let numberOfChannels = + state.settings[0].mixers[mixerIndex].numberOfChannelsInType[0] + + for (let i = 0; i < numberOfChannels; i++) { + assignedFader = + state.channels[0].chMixerConnection[mixerIndex].channel[i] + .assignedFader + if ( + assignedFader >= 0 && + assignedFader < state.settings[0].numberOfFaders + ) { + level = calcVuLevel(dataview.getFloat32(4 * i + DATA_OFFSET, true)) + reductionLevel = dataview.getFloat32( + 4 * (i + 64) + DATA_OFFSET, + true + ) + let vuIndex: number = state.faders[0].fader[ + assignedFader + ].assignedChannels?.findIndex((assigned) => { + return ( + assigned.mixerIndex === mixerIndex && + assigned.channelIndex === i + ) + }) + if (vuIndex === -1) vuIndex = 0 + sendVuLevel(assignedFader, VuType.Channel, vuIndex, level) + sendVuLevel(assignedFader, VuType.Reduction, 0, 1 - reductionLevel) + } + } +} diff --git a/server/src/utils/remoteConnections/HuiMidiRemoteConnection.ts b/server/src/utils/remoteConnections/HuiMidiRemoteConnection.ts new file mode 100644 index 00000000..2177fe1a --- /dev/null +++ b/server/src/utils/remoteConnections/HuiMidiRemoteConnection.ts @@ -0,0 +1,190 @@ +//Node Modules: +import WebMidi from 'webmidi' +import { store, state } from '../../reducers/store' +import { mixerGenericConnection } from '../../mainClasses' + +import { + storeFaderLevel, + storeTogglePgm, + storeTogglePfl, +} from '../../../../shared/src/actions/faderActions' + +//Utils: +import { + IRemoteProtocol, + RemoteFaderPresets, + MidiReceiveTypes, +} from '../../../../shared/src/constants/remoteProtocols/HuiRemoteFaderPresets' +import { MixerProtocolPresets } from '../../../../shared/src/constants/MixerProtocolPresets' +import { logger } from '../logger' + +export class HuiMidiRemoteConnection { + store: any + remoteProtocol: IRemoteProtocol + midiReceiveTypes = MidiReceiveTypes + mixerProtocol: any + midiInput: any + midiOutput: any + activeHuiChannel: number = 0 + + constructor() { + this.convertFromRemoteLevel = this.convertFromRemoteLevel.bind(this) + this.convertToRemoteLevel = this.convertToRemoteLevel.bind(this) + this.updateRemoteFaderState = this.updateRemoteFaderState.bind(this) + + this.remoteProtocol = RemoteFaderPresets.hui + this.mixerProtocol = + MixerProtocolPresets[state.settings[0].mixers[0].mixerProtocol] || + MixerProtocolPresets.genericMidi + + if (!state.settings[0].enableRemoteFader) { + return + } + + WebMidi.enable((err) => { + if (err) { + logger + .data(err) + .error( + 'Remote MidiController connection could not be enabled.' + ) + } + + this.midiInput = WebMidi.getInputByName( + state.settings[0].remoteFaderMidiInputPort + ) + this.midiOutput = WebMidi.getOutputByName( + state.settings[0].remoteFaderMidiOutputPort + ) + + if (this.midiInput && this.midiOutput) { + logger.info('Remote Midi Controller connected on port') + logger.info( + `Midi input : ${state.settings[0].remoteFaderMidiInputPort}` + ) + logger.info( + `Midi output : ${state.settings[0].remoteFaderMidiOutputPort}` + ) + this.setupRemoteFaderConnection() + } else { + logger.error( + 'Remote Midi Controller not found or not configured.' + ) + } + }) + } + + setupRemoteFaderConnection() { + this.midiInput.addListener( + this.midiReceiveTypes[ + this.remoteProtocol.fromRemote.CHANNEL_FADER_LEVEL.type + ], + undefined, + (message: any) => { + if (message.data[1] < 9) { + //Fader changed: + logger.info(`Received Fader message (${message.data}).`) + store.dispatch( + storeFaderLevel( + message.data[1], + this.convertFromRemoteLevel(message.data[2]) + ) + ) + mixerGenericConnection.updateOutLevel(message.data[1], -1) + this.updateRemoteFaderState( + message.data[1], + this.convertFromRemoteLevel(message.data[2]) + ) + } else if ((message.data[1] = 15)) { + logger.info(`Received message (${message.data}).`) + if (message.data[2] < 9) { + //Set active channel for next midi message: + this.activeHuiChannel = message.data[2] + } else if (message.data[2] && message.data[2] === 65) { + //SELECT button - toggle PGM ON/OFF + store.dispatch(storeTogglePgm(this.activeHuiChannel)) + mixerGenericConnection.updateOutLevel( + this.activeHuiChannel, -1 + ) + this.updateRemotePgmPstPfl(this.activeHuiChannel) + } else if (message.data[2] && message.data[2] === 67) { + //SOLO button - toggle PFL ON/OFF + store.dispatch(storeTogglePfl(this.activeHuiChannel)) + mixerGenericConnection.updateOutLevel( + this.activeHuiChannel, -1 + ) + this.updateRemotePgmPstPfl(this.activeHuiChannel) + } + } + } + ) + //for testing: + this.midiInput.addListener('noteon', 'all', (error: any) => { + logger.info( + `Received 'noteon' message (${error.note.name} ${error.note.octave}).` + ) + }) + } + + convertToRemoteLevel(level: number) { + let oldMin = this.mixerProtocol.fader.min + let oldMax = this.mixerProtocol.fader.max + let newMin = this.remoteProtocol.fader.min + let newMax = this.remoteProtocol.fader.max + + let indexLevel = (level / (oldMax - oldMin)) * (newMax - newMin) + let newLevel = newMin + indexLevel + return newLevel //convert from mixer min-max to remote min-max + } + + convertFromRemoteLevel(level: number) { + let oldMin = this.remoteProtocol.fader.min + let oldMax = this.remoteProtocol.fader.max + let newMin = this.mixerProtocol.fader.min + let newMax = this.mixerProtocol.fader.max + + let indexLevel = (level / (oldMax - oldMin)) * (newMax - newMin) + let newLevel = newMin + indexLevel + + return newLevel //convert from mixer min-max to remote min-max + } + + updateRemoteFaderState(channelIndex: number, outputLevel: number) { + if (!this.midiOutput) { + return + } + logger.info( + `Send fader update : Channel index : ${channelIndex} OutputLevel : ${this.convertToRemoteLevel( + outputLevel + )}` + ) + this.midiOutput.sendControlChange( + channelIndex, + this.convertToRemoteLevel(outputLevel), + 1 + ) + this.midiOutput.sendControlChange(32 + channelIndex, 0, 1) + this.updateRemotePgmPstPfl(channelIndex) + } + + updateRemotePgmPstPfl(channelIndex: number) { + if (!this.midiOutput) { + return + } + //Update SELECT button: + this.midiOutput.sendControlChange(12, channelIndex, 1) + this.midiOutput.sendControlChange( + 44, + 1 + 64 * (state.faders[0].fader[channelIndex].pgmOn ? 1 : 0), + 1 + ) + + //Update SOLO button: + this.midiOutput.sendControlChange(12, channelIndex, 1) + this.midiOutput.sendControlChange( + 44, + 3 + 64 * (state.faders[0].fader[channelIndex].pflOn ? 1 : 0), + 1 + ) + } +} diff --git a/server/src/utils/remoteConnections/SkaarhojRemoteConnection.ts b/server/src/utils/remoteConnections/SkaarhojRemoteConnection.ts new file mode 100644 index 00000000..00ee4a13 --- /dev/null +++ b/server/src/utils/remoteConnections/SkaarhojRemoteConnection.ts @@ -0,0 +1,262 @@ +//Node Modules: +import net from 'net' +import { store, state } from '../../reducers/store' +import { mixerGenericConnection } from '../../mainClasses' + +import { storeFaderLevel } from '../../../../shared/src/actions/faderActions' + +//Utils: +import { + IRemoteProtocol, + RemoteFaderPresets, +} from '../../../../shared/src/constants/remoteProtocols/SkaarhojProtocol' +import { MixerProtocolPresets } from '../../../../shared/src/constants/MixerProtocolPresets' +import { logger } from '../logger' +import { storeSetAuxLevel } from '../../../../shared/src/actions/channelActions' + +export class SkaarhojRemoteConnection { + store: any + remoteProtocol: IRemoteProtocol + mixerProtocol: any + clientList: any[] + + constructor() { + this.updateRemoteFaderState = this.updateRemoteFaderState.bind(this) + + this.remoteProtocol = RemoteFaderPresets.rawPanel + this.mixerProtocol = + MixerProtocolPresets[state.settings[0].mixers[0].mixerProtocol] || + MixerProtocolPresets.genericMidi + this.clientList = [] + + const server = net.createServer((client: any) => { + this.clientList.push(client) + this.setupRemoteFaderConnection(client) + }) + + server.listen(9923, '0.0.0.0') + logger.info('Skaarhoj server listening at port 9923') + } + + setupRemoteFaderConnection(client: any) { + client + .on('data', (data: any) => { + logger.debug('Skaarhoj Data Received: ' + data.toString()) + data.toString() + .split('\n') + .forEach((command: string) => { + if (command === 'RDY') { + client.write('ready ok\n') + } else if (command === 'list') { + logger.info('Activating Skaarhoj panel') + client.write('ActivePanel=1\n') + } else if (command.includes('map=')) { + this.initializeMapping(command) + } else if (command === 'ping') { + client.write('pingo\n') + } else if (command === 'ack') { + client.write('ack\n') + } else if (command.substring(0, 4) === 'HWC#') { + this.handleRemoteCommand(command) + } + }) + }) + .on('error', function () { + if (this.clientList) { + this.clientList.splice(this.clientList.find(client), 1) + } + logger.error('Lost Connection to Skaarhoj panel') + }) + .on('close', function () { + if (this.clientList) { + this.clientList.splice(this.clientList.find(client), 1) + } + logger.info('Skaarhoj Connection closed') + }) + } + + initializeMapping(command: string) { + let hwButton = parseInt(command.substring(command.indexOf(':') + 1)) + // Initialize: + logger.info('Initializing Skaarhoj remote') + if (hwButton <= state.faders[0].fader.length) { + logger.data(hwButton).info('Initializing skaahoj fader - Button') + this.updateRemoteFaderState( + hwButton - 1, + state.faders[0].fader[hwButton - 1].faderLevel + ) + } + this.updateRemoteAuxPanels() + } + + handleRemoteCommand(command: string) { + let btnNumber = parseInt( + command.slice(command.indexOf('#') + 1, command.indexOf('=')) + ) + let event = command.slice(command.indexOf('=') + 1) + if (btnNumber <= state.faders[0].fader.length) { + let channelIndex = btnNumber - 1 + let level = state.faders[0].fader[channelIndex].faderLevel + if (event === 'Enc:1') { + level += 0.01 + if (level > 1) { + level = 1 + } + } else if (event === 'Enc:2') { + level += 0.1 + if (level < 0) { + level = 0 + } + } else if (event === 'Enc:-1') { + level -= 0.01 + if (level < 0) { + level = 0 + } + } else if (event === 'Enc:-2') { + level -= 0.1 + if (level < 0) { + level = 0 + } + } + //Fader changed: + logger.debug(`Received Fader ${channelIndex + 1} Level : ${level}`) + store.dispatch(storeFaderLevel(channelIndex, level)) + mixerGenericConnection.updateOutLevel(channelIndex, -1) + global.mainThreadHandler.updatePartialStore(channelIndex) + this.updateRemoteFaderState(channelIndex, level) + } else if (btnNumber > 80) { + this.handleAuxLevelCommand(command, btnNumber) + } + } + + handleAuxLevelCommand(command: string, btnNumber: number) { + let auxBtnNumber = + btnNumber - parseInt((btnNumber / 10).toFixed(0)) * 10 + if (auxBtnNumber > 9) { + return + } + let panelNumber = (btnNumber - auxBtnNumber - 70) / 10 + let faderIndex = panelNumber - 1 + let auxSendIndex = state.faders[0].fader[faderIndex].monitor - 1 + if (auxSendIndex < 0) { + return + } + let chIndex = 0 + let btnIndex = 1 + state.channels[0].chMixerConnection[0].channel.forEach( + (ch: any, index: number) => { + if (ch.auxLevel[auxSendIndex] >= 0) { + if (btnIndex === auxBtnNumber) { + chIndex = index + btnIndex++ + } else if (btnIndex < auxBtnNumber) { + btnIndex++ + } + } + } + ) + + let event = command.slice(command.indexOf('=') + 1) + let level = + state.channels[0].chMixerConnection[0].channel[chIndex].auxLevel[ + auxSendIndex + ] + if (event === 'Enc:1') { + level += 0.01 + if (level > 1) { + level = 1 + } + } else if (event === 'Enc:2') { + level += 0.1 + if (level < 0) { + level = 0 + } + } else if (event === 'Enc:-1') { + level -= 0.01 + if (level < 0) { + level = 0 + } + } else if (event === 'Enc:-2') { + level -= 0.1 + if (level < 0) { + level = 0 + } + } + //Fader changed: + logger.info( + `Received Aux Panel ${panelNumber} Ch ${ + chIndex + 1 + } Level: ${level}` + ) + store.dispatch(storeSetAuxLevel(0, chIndex, auxSendIndex, level)) + mixerGenericConnection.updateAuxLevel(chIndex, auxSendIndex + 1) + global.mainThreadHandler.updateFullClientStore() + this.updateRemoteAuxPanel(panelNumber) + } + + updateRemoteFaderState(channelIndex: number, outputLevel: number) { + let formatLevel = (outputLevel * 100).toFixed() + let formatLabel = + state.faders[0].fader[channelIndex]?.label || + 'CH' + String(channelIndex + 1) + let formattetString = + 'HWCt#' + + String(channelIndex + 1) + + '=' + + formatLevel + + '|||||' + + formatLabel + + '\n' + // 32767|||||label + logger.trace(`Sending command to Skaarhoj : ${formattetString}`) + this.clientList.forEach((client) => { + client.write(formattetString) + }) + } + + updateRemoteAuxPanels() { + for (let index = 1; index <= 3; index++) { + this.updateRemoteAuxPanel(index) + } + } + + updateRemoteAuxPanel(panelNumber: number) { + let faderIndex = panelNumber - 1 + let auxSendIndex = state.faders[0].fader[faderIndex].monitor - 1 + if (auxSendIndex < 0) { + return + } + let hwButton = panelNumber * 10 + 70 + 1 + state.channels[0].chMixerConnection[0].channel.forEach( + (ch: any, index: number) => { + if ( + ch.auxLevel[auxSendIndex] >= 0 && + hwButton <= panelNumber * 10 + 70 + 9 + ) { + let formatLevel = ( + ch.auxLevel[auxSendIndex] * 100 + ).toFixed() + let formatLabel = + state.faders[0].fader[ch.assignedFader]?.label || + 'CH' + String(index + 1) + let formattetString = + 'HWCt#' + + String(hwButton) + + '=' + + formatLevel + + '|||||' + + formatLabel + + '\n' + hwButton++ + this.clientList.forEach((client) => { + client.write(formattetString) + }) + } + } + ) + } + + updateRemotePgmPstPfl(channelIndex: number) { + return + } +} diff --git a/server/src/utils/vuServer.ts b/server/src/utils/vuServer.ts new file mode 100644 index 00000000..26c10370 --- /dev/null +++ b/server/src/utils/vuServer.ts @@ -0,0 +1,28 @@ +import { VuType } from '../../../shared/src/utils/vu-server-types' + +const sockets: Array = [] + +export function socketSubscribeVu(socket: any) { + const i = sockets.indexOf(socket) + if (i === -1) { + sockets.push(socket) + } +} + +export function socketUnsubscribeVu(socket: any) { + const i = sockets.indexOf(socket) + if (i >= 0) { + sockets.splice(i, 1) + } +} + +export function sendVuLevel( + faderIndex: number, + type: VuType, + channelIndex: number, + level: number +) { + sockets.forEach((socket) => { + socket.emit(type, faderIndex, channelIndex, level) + }) +} diff --git a/server/tsconfig.json b/server/tsconfig.json index b2304720..afd5c856 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -1,23 +1,17 @@ -{ - "compilerOptions": { - // Target latest version of ECMAScript. - "target": "ES5", - // Search under node_modules for non-relative imports. - "moduleResolution": "node", - // Process & infer types from .js files. - "allowJs": false, - // Enable strictest settings like strictNullChecks & noImplicitAny. - "strict": false, - // Disallow features that require cross-file information for emit. - "isolatedModules": false, - // Import non-ES modules as default imports. - "esModuleInterop": true, - // Check for "any" while converting to TS this can be turned off. - "noImplicitAny": true, - "module": "commonjs", - "outDir": "../dist/server", - }, - "include": [ - "*" - ] -} +{ + "compilerOptions": { + "target": "esnext", + "lib": ["esnext", "dom"], + "moduleResolution": "node", + "allowJs": false, + "strict": false, + "isolatedModules": false, + "esModuleInterop": true, + "noImplicitAny": false, + "resolveJsonModule": true, + "module": "commonjs", + "outDir": "dist" + }, + "include": ["../server", "../../shared"], + "exclude": ["node_modules/*", "dist/*", "**/*.spec.ts"] +} diff --git a/server/utils/AutomationConnection.ts b/server/utils/AutomationConnection.ts deleted file mode 100644 index d2518ced..00000000 --- a/server/utils/AutomationConnection.ts +++ /dev/null @@ -1,320 +0,0 @@ -//Node Modules: -const osc = require('osc') -import { store, state } from '../reducers/store' -import { mixerGenericConnection } from '../mainClasses' - -//Utils: -import { IAutomationProtocol, AutomationPresets } from '../constants/AutomationPresets'; -import { IFader } from '../reducers/fadersReducer'; -import { - SET_FADER_LEVEL, - SET_CHANNEL_LABEL, - SET_PGM, - SET_VO, - SET_PST, - SET_PST_VO, - SET_MUTE, - SHOW_CHANNEL, - X_MIX, - FADE_TO_BLACK, - CLEAR_PST, - SNAP_RECALL -} from '../reducers/faderActions' -import { logger } from './logger'; - - -const AUTOMATION_OSC_PORT = 5255; -export class AutomationConnection { - oscConnection: any; - automationProtocol: IAutomationProtocol; - - constructor() { - this.sendOutMessage = this.sendOutMessage.bind(this); - - this.automationProtocol = AutomationPresets.sofie; - - this.oscConnection = new osc.UDPPort({ - localAddress: "0.0.0.0", - localPort: AUTOMATION_OSC_PORT - }); - this.setupAutomationConnection(); - } - - setupAutomationConnection() { - this.oscConnection - .on("ready", () => { - this.automationProtocol.initializeCommands.map((item) => { - // this.sendOutMessage(item.oscMessage, 1, item.value, item.type); - logger.info("Listening for Automation via OSC over UDP.", {}) - }); - }) - .on('message', (message: any, timetag: number | undefined, info: any) => { - logger.info("RECIEVED AUTOMATION MESSAGE :" + message.address + message.args[0], {}) - //Set state of Sisyfos: - if ( this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .CHANNEL_PGM_ON_OFF)){ - let ch = message.address.split("/")[2]; - if (!state.faders[0].fader[ch - 1].ignoreAutomation) { - if (message.args[0] === 1) { - mixerGenericConnection.checkForAutoResetThreshold(ch - 1) - store.dispatch({ - type: SET_PGM, - channel: ch - 1, - pgmOn: true - }); - } else if (message.args[0] === 2) { - mixerGenericConnection.checkForAutoResetThreshold(ch - 1) - store.dispatch({ - type: SET_VO, - channel: ch - 1, - voOn: true - }); - } else { - store.dispatch({ - type: SET_PGM, - channel: ch - 1, - pgmOn: false - }); - } - - if (message.args.length > 1) { - mixerGenericConnection.updateOutLevel(ch-1, parseFloat(message.args[1])); - } else { - mixerGenericConnection.updateOutLevel(ch-1); - } - } - global.mainThreadHandler.updatePartialStore(ch - 1) - } else if ( this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .CHANNEL_PST_ON_OFF)){ - let ch = message.address.split("/")[2]; - if (!state.faders[0].fader[ch - 1].ignoreAutomation) { - - if (message.args[0] === 1) { - store.dispatch({ - type: SET_PST, - channel: ch - 1, - pstOn: true - }); - } else if (message.args[0] === 2) { - store.dispatch({ - type: SET_PST_VO, - channel: ch - 1, - pstVoOn: true - }); - } else { - store.dispatch({ - type: SET_PST, - channel: ch - 1, - pstOn: false - }); - } - mixerGenericConnection.updateNextAux(ch-1); - global.mainThreadHandler.updatePartialStore(ch - 1) - } - } else if ( this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .CHANNEL_MUTE)){ - let ch = message.address.split("/")[2]; - if (!state.faders[0].fader[ch - 1].ignoreAutomation) { - - if (message.args[0] === 1) { - store.dispatch({ - type: SET_MUTE, - channel: ch - 1, - muteOn: true - }); - } else { - store.dispatch({ - type: SET_MUTE, - channel: ch - 1, - pstOn: false - }); - } - mixerGenericConnection.updateMuteState(ch-1) - global.mainThreadHandler.updatePartialStore(ch - 1) - - } - } else if ( this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .CHANNEL_FADER_LEVEL)){ - let ch = message.address.split("/")[2]; - if (!state.faders[0].fader[ch - 1].ignoreAutomation) { - - store.dispatch({ - type: SET_FADER_LEVEL, - channel: ch - 1, - level: message.args[0] - }); - mixerGenericConnection.updateOutLevel(ch-1) - global.mainThreadHandler.updatePartialStore(ch - 1) - } - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .INJECT_COMMAND)) { - let ch = message.address.split("/")[2]; - store.dispatch({ - type: SET_CHANNEL_LABEL, - channel: ch -1, - label: message.args[0] - }); - mixerGenericConnection.injectCommand(message.args) - global.mainThreadHandler.updatePartialStore(ch - 1) - - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .SNAP_RECALL)) { - let snapNumber = message.address.split("/")[2]; - store.dispatch({ - type: SNAP_RECALL, - snapIndex: snapNumber -1 - }); - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .SET_LABEL)) { - let ch = message.address.split("/")[2]; - store.dispatch({ - type: SET_CHANNEL_LABEL, - channel: ch -1, - label: message.args[0] - }); - mixerGenericConnection.updateChannelName(ch-1) - global.mainThreadHandler.updatePartialStore(ch - 1) - - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .X_MIX)) { - store.dispatch({ - type: X_MIX - }); - mixerGenericConnection.updateOutLevels(); - global.mainThreadHandler.updateFullClientStore() - } else if ( this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .CHANNEL_VISIBLE)){ - let ch = message.address.split("/")[2]; - store.dispatch({ - type: SHOW_CHANNEL, - channel: ch - 1, - showChannel: message.args[0]===1 ? true : false - }); - global.mainThreadHandler.updatePartialStore(ch - 1) - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .FADE_TO_BLACK)) { - store.dispatch({ - type: FADE_TO_BLACK - }); - mixerGenericConnection.updateFadeToBlack(); - global.mainThreadHandler.updateFullClientStore() - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .CLEAR_PST)) { - store.dispatch({ - type: CLEAR_PST - }); - mixerGenericConnection.updateOutLevels(); - global.mainThreadHandler.updateFullClientStore() - // Get state from Producers Audio Mixer: - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .STATE_FULL)) { - this.sendOutMessage( - this.automationProtocol.toAutomation.STATE_FULL, - 0, - JSON.stringify({ - channel: state.faders[0].fader.map(({ faderLevel, pgmOn, voOn, pstOn, showChannel }: IFader) => ({ - faderLevel, pgmOn, voOn, pstOn, showChannel - })) - }), - "s", - info - ) - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .STATE_CHANNEL_PGM)) { - let ch = message.address.split("/")[3]; - this.sendOutMessage( - this.automationProtocol.toAutomation.STATE_CHANNEL_PGM, - ch, - state.faders[0].fader[ch-1].pgmOn, - "i", - info - ); - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .STATE_CHANNEL_PST)) { - let ch = message.address.split("/")[3]; - this.sendOutMessage( - this.automationProtocol.toAutomation.STATE_CHANNEL_PST, - ch, - state.faders[0].fader[ch-1].pstOn, - "i", - info - ); - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .STATE_CHANNEL_MUTE)) { - let ch = message.address.split("/")[3]; - this.sendOutMessage( - this.automationProtocol.toAutomation.STATE_CHANNEL_MUTE, - ch, - state.faders[0].fader[ch-1].muteOn, - "i", - info - ); - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .STATE_CHANNEL_FADER_LEVEL)) { - let ch = message.address.split("/")[3]; - this.sendOutMessage( - this.automationProtocol.toAutomation.STATE_CHANNEL_FADER_LEVEL, - ch, - state.faders[0].fader[ch-1].faderLevel, - "f", - info - ); - } else if (this.checkOscCommand(message.address, this.automationProtocol.fromAutomation - .PING)) { - let pingValue = state.settings[0].mixerOnline ? message.address.split("/")[2] : 'offline'; - - this.sendOutMessage( - this.automationProtocol.toAutomation.PONG, - 0, - pingValue, - "s", - info - ) - } - }) - .on('error', (error: any) => { - logger.error("Error : ", error) - logger.info("Lost OSC Automation connection", {}) - }); - - this.oscConnection.open(); - logger.info('OSC Automation listening on port ' + String(AUTOMATION_OSC_PORT), {}) - - } - - checkOscCommand(message: string, command: string) { - if (message === command) return true; - - let cmdArray = command.split("{value1}"); - - if ( - message.substr(0, cmdArray[0].length) === cmdArray[0] && - (message.substr(-cmdArray[1].length) === cmdArray[1] || cmdArray[1].length === 0 ) && - message.length >= command.replace("{value1}", "").length - ) { - return true; - } else { - return false; - } - } - - sendOutMessage(oscMessage: string, channel: number, value: string | number | boolean, type: string, to: { address: string, port: number }) { - let channelString = this.automationProtocol.leadingZeros ? ("0"+channel).slice(-2) : channel.toString(); - let message = oscMessage.replace( - "{value1}", - channelString - ); - if (message != 'none') { - this.oscConnection.send({ - address: message, - args: [ - { - type: type, - value: value - } - ] - }, to.address, to.port); - } - } -} - diff --git a/server/utils/HuiMidiRemoteConnection.ts b/server/utils/HuiMidiRemoteConnection.ts deleted file mode 100644 index f76eb864..00000000 --- a/server/utils/HuiMidiRemoteConnection.ts +++ /dev/null @@ -1,177 +0,0 @@ -//Node Modules: -import WebMidi from 'webmidi'; -import { store, state } from '../reducers/store' -import { mixerGenericConnection } from '../mainClasses' - -import { - SET_FADER_LEVEL, - TOGGLE_PGM, - TOGGLE_PFL -} from '../reducers/faderActions' - -//Utils: -import { IRemoteProtocol, - RemoteFaderPresets, - MidiReceiveTypes -} from '../constants/RemoteFaderPresets'; -import { MixerProtocolPresets } from '../constants/MixerProtocolPresets'; - -export class HuiMidiRemoteConnection { - store: any; - remoteProtocol: IRemoteProtocol; - midiReceiveTypes = MidiReceiveTypes; - mixerProtocol: any; - midiInput: any; - midiOutput:any; - activeHuiChannel: number = 0; - - constructor() { - this.convertFromRemoteLevel = this.convertFromRemoteLevel.bind(this); - this.convertToRemoteLevel = this.convertToRemoteLevel.bind(this); - this.updateRemoteFaderState = this.updateRemoteFaderState.bind(this); - - this.remoteProtocol = RemoteFaderPresets.hui; - this.mixerProtocol = MixerProtocolPresets[state.settings[0].mixerProtocol] || MixerProtocolPresets.genericMidi; - - if (!state.settings[0].enableRemoteFader) { - return - } - - WebMidi.enable((err) => { - if (err) { - console.log("Remote MidiController connection could not be enabled.", err); - } - - this.midiInput = WebMidi.getInputByName(state.settings[0].remoteFaderMidiInputPort); - this.midiOutput = WebMidi.getOutputByName(state.settings[0].remoteFaderMidiOutputPort); - - if (this.midiInput && this.midiOutput ) { - console.log("Remote Midi Controller connected on port") - console.log("Midi input :", state.settings[0].remoteFaderMidiInputPort) - console.log("Midi output :", state.settings[0].remoteFaderMidiOutputPort) - - this.setupRemoteFaderConnection(); - } else { - console.log("Remote Midi Controller not found or not configured.") - } - }); - } - - setupRemoteFaderConnection() { - this.midiInput.addListener(this.midiReceiveTypes[this.remoteProtocol.fromRemote.CHANNEL_FADER_LEVEL.type], undefined, - (message: any) => { - if (message.data[1] < 9) { - //Fader changed: - console.log("Received Fader message (" + message.data + ")."); - store.dispatch({ - type: SET_FADER_LEVEL, - channel: message.data[1], - level: this.convertFromRemoteLevel(message.data[2]) - }); - mixerGenericConnection.updateOutLevel(message.data[1]); - this.updateRemoteFaderState(message.data[1], this.convertFromRemoteLevel(message.data[2])) - } else if (message.data[1] = 15) { - - console.log("Received message (" + message.data + ")."); - if (message.data[2]<9) { - //Set active channel for next midi message: - this.activeHuiChannel = message.data[2]; - } else if (message.data[2] && message.data[2] === 65) { - //SELECT button - toggle PGM ON/OFF - store.dispatch({ - type: TOGGLE_PGM, - channel: this.activeHuiChannel - }); - mixerGenericConnection.updateOutLevel(this.activeHuiChannel); - this.updateRemotePgmPstPfl(this.activeHuiChannel); - } else if (message.data[2] && message.data[2] === 67) { - //SOLO button - toggle PFL ON/OFF - store.dispatch({ - type: TOGGLE_PFL, - channel: this.activeHuiChannel - }); - mixerGenericConnection.updateOutLevel(this.activeHuiChannel); - this.updateRemotePgmPstPfl(this.activeHuiChannel); - } - } - } - ); - //for testing: - this.midiInput.addListener('noteon', "all", - (error: any) => { - console.log("Received 'noteon' message (" + error.note.name + error.note.octave + ")."); - } - ); - - } - - convertToRemoteLevel(level: number) { - - let oldMin = this.mixerProtocol.fader.min; - let oldMax = this.mixerProtocol.fader.max; - let newMin = this.remoteProtocol.fader.min; - let newMax = this.remoteProtocol.fader.max; - - let indexLevel = (level/(oldMax-oldMin)) * (newMax-newMin) - let newLevel = newMin + indexLevel; - return newLevel //convert from mixer min-max to remote min-max - } - - convertFromRemoteLevel(level: number) { - - let oldMin = this.remoteProtocol.fader.min; - let oldMax = this.remoteProtocol.fader.max; - let newMin = this.mixerProtocol.fader.min; - let newMax = this.mixerProtocol.fader.max; - - let indexLevel = (level/(oldMax-oldMin)) * (newMax-newMin) - let newLevel = newMin + indexLevel; - - return newLevel //convert from mixer min-max to remote min-max - } - - updateRemoteFaderState(channelIndex: number, outputLevel: number) { - if (!this.midiOutput) { return }; - console.log("Send fader update :", "Channel index : ", channelIndex, "OutputLevel : ", this.convertToRemoteLevel(outputLevel)) - this.midiOutput.sendControlChange( - (channelIndex), - this.convertToRemoteLevel(outputLevel), - 1 - ); - this.midiOutput.sendControlChange( - (32+channelIndex), - 0, - 1 - ); - this.updateRemotePgmPstPfl(channelIndex) - - } - - updateRemotePgmPstPfl(channelIndex: number) { - if (!this.midiOutput) { return }; - //Update SELECT button: - this.midiOutput.sendControlChange( - 12, - channelIndex, - 1 - ); - this.midiOutput.sendControlChange( - 44, - 1 + (64*(state.faders[0].fader[channelIndex].pgmOn ? 1 : 0)), - 1 - ); - - //Update SOLO button: - this.midiOutput.sendControlChange( - 12, - channelIndex, - 1 - ); - this.midiOutput.sendControlChange( - 44, - 3 + (64*(state.faders[0].fader[channelIndex].pflOn ? 1 : 0)), - 1 - ); - } -} - diff --git a/server/utils/MixerConnection.ts b/server/utils/MixerConnection.ts deleted file mode 100644 index 7f92883a..00000000 --- a/server/utils/MixerConnection.ts +++ /dev/null @@ -1,361 +0,0 @@ -import { store, state } from '../reducers/store' -import { huiRemoteConnection } from '../mainClasses' - -//Utils: -import { MixerProtocolPresets } from '../constants/MixerProtocolPresets'; -import { IMixerProtocol, IMixerProtocolGeneric, ICasparCGMixerGeometry } from '../constants/MixerProtocolInterface'; -import { OscMixerConnection } from './mixerConnections/OscMixerConnection'; -import { MidiMixerConnection } from './mixerConnections/MidiMixerConnection'; -import { QlClMixerConnection } from './mixerConnections/YamahaQlClConnection'; -import { SSLMixerConnection } from './mixerConnections/SSLMixerConnection'; -import { EmberMixerConnection } from './mixerConnections/EmberMixerConnection'; -import { CasparCGConnection } from './mixerConnections/CasparCGConnection'; -import { IChannel } from '../reducers/channelsReducer'; -import { SET_OUTPUT_LEVEL, FADE_ACTIVE } from '../reducers/channelActions' -import { SET_FADER_LEVEL } from '../reducers/faderActions' - - -// FADE_INOUT_SPEED defines the resolution of the fade in ms -// The lower the more CPU -const FADE_INOUT_SPEED = 3; -const FADE_DISPATCH_RESOLUTION = 5; - -export class MixerGenericConnection { - store: any; - mixerProtocol: IMixerProtocolGeneric; - mixerConnection: any; - timer: any; - fadeActiveTimer: any; - - constructor() { - this.updateOutLevels = this.updateOutLevels.bind(this); - this.updateOutLevel = this.updateOutLevel.bind(this); - this.fadeInOut = this.fadeInOut.bind(this); - this.fadeUp = this.fadeUp.bind(this); - this.fadeDown = this.fadeDown.bind(this); - this.clearTimer = this.clearTimer.bind(this) - - // Get mixer protocol - this.mixerProtocol = MixerProtocolPresets[state.settings[0].mixerProtocol] || MixerProtocolPresets.sslSystemT; - if (this.mixerProtocol.protocol === 'OSC') { - this.mixerConnection = new OscMixerConnection(this.mixerProtocol as IMixerProtocol); - } else if (this.mixerProtocol.protocol === 'QLCL') { - this.mixerConnection = new QlClMixerConnection(this.mixerProtocol as IMixerProtocol); - } else if (this.mixerProtocol.protocol === 'MIDI') { - this.mixerConnection = new MidiMixerConnection(this.mixerProtocol as IMixerProtocol); - } else if (this.mixerProtocol.protocol === 'CasparCG') { - this.mixerConnection = new CasparCGConnection(this.mixerProtocol as ICasparCGMixerGeometry); - } else if (this.mixerProtocol.protocol === 'EMBER') { - this.mixerConnection = new EmberMixerConnection(this.mixerProtocol as IMixerProtocol); - } else if (this.mixerProtocol.protocol === 'SSL') { - this.mixerConnection = new SSLMixerConnection(this.mixerProtocol as IMixerProtocol); - } - - //Setup timers for fade in & out - this.timer = new Array(state.channels[0].channel.length); - this.fadeActiveTimer = new Array(state.channels[0].channel.length); - } - - - checkForAutoResetThreshold(channel: number) { - if (state.faders[0].fader[channel].faderLevel <= this.mixerProtocol.fader.min + (this.mixerProtocol.fader.max * state.settings[0].autoResetLevel / 100)) { - store.dispatch({ - type: SET_FADER_LEVEL, - channel: channel, - level: this.mixerProtocol.fader.zero - }) - } - } - - - updateFadeToBlack() { - state.faders[0].fader.map((channel: any, index: number) => { - this.updateOutLevel(index); - }); - } - - updateOutLevels() { - state.faders[0].fader.map((channel: any, index: number) => { - this.updateOutLevel(index); - this.updateNextAux(index); - }); - } - - updateOutLevel(faderIndex: number, fadeTime: number = -1) { - if (fadeTime === -1) { - if (state.faders[0].fader[faderIndex].voOn) { - fadeTime = state.settings[0].voFadeTime - } else { - fadeTime = state.settings[0].fadeTime - } - } - - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.fadeInOut(channelIndex, fadeTime); - } - }) - if (huiRemoteConnection) { - huiRemoteConnection.updateRemoteFaderState(faderIndex, state.faders[0].fader[faderIndex].faderLevel) - } - } - - updatePflState(channelIndex: number) { - this.mixerConnection.updatePflState(channelIndex); - } - - updateMuteState(faderIndex: number) { - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.mixerConnection.updateMuteState(channelIndex, state.faders[0].fader[faderIndex].muteOn) - } - }) - } - - updateNextAux(faderIndex: number) { - let level = 0 - if (state.faders[0].fader[faderIndex].pstOn) { - level = state.faders[0].fader[faderIndex].faderLevel - } else if (state.faders[0].fader[faderIndex].pstVoOn) { - level = state.faders[0].fader[faderIndex].faderLevel * (100-state.settings[0].voLevel)/100 - } - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.mixerConnection.updateNextAux(channelIndex, level) - } - }) - } - - updateThreshold(faderIndex: number) { - let level = state.faders[0].fader[faderIndex].threshold - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.mixerConnection.updateThreshold(channelIndex, level) - } - }) - } - updateRatio(faderIndex: number) { - let level = state.faders[0].fader[faderIndex].ratio - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.mixerConnection.updateRatio(channelIndex, level) - } - }) - } - updateDelayTime(faderIndex: number) { - let delayTime = state.faders[0].fader[faderIndex].delayTime - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.mixerConnection.updateDelayTime(channelIndex, delayTime) - } - }) - } - updateLow(faderIndex: number) { - let level = state.faders[0].fader[faderIndex].low - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.mixerConnection.updateLow(channelIndex, level) - } - }) - } - updateLoMid(faderIndex: number) { - let level = state.faders[0].fader[faderIndex].loMid - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.mixerConnection.updateLoMid(channelIndex, level) - } - }) - } - updateMid(faderIndex: number) { - let level = state.faders[0].fader[faderIndex].mid - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.mixerConnection.updateMid(channelIndex, level) - } - }) - } - updateHigh(faderIndex: number) { - let level = state.faders[0].fader[faderIndex].high - state.channels[0].channel.map((channel: IChannel, channelIndex: number) => { - if (faderIndex === channel.assignedFader) { - this.mixerConnection.updateHigh(channelIndex, level) - } - }) - } - - updateAuxLevel(channelIndex: number, auxSendIndex: number) { - let channel = state.channels[0].channel[channelIndex] - if (channel.auxLevel[auxSendIndex] > -1) { - this.mixerConnection.updateAuxLevel(channelIndex, auxSendIndex, channel.auxLevel[auxSendIndex]) - } - } - - updateChannelName(channelIndex: number) { - this.mixerConnection.updateChannelName(channelIndex); - } - - injectCommand(command: string[]) { - this.mixerConnection.injectCommand(command) - } - - updateChannelSettings(channelIndex: number, setting: string, value: string) { - if (this.mixerProtocol.protocol === 'CasparCG') { - this.mixerConnection.updateChannelSetting(channelIndex, setting, value) - } - } - - clearTimer(channelIndex: number) { - clearInterval(this.timer[channelIndex]); - } - - delayedFadeActiveDisable (channelIndex: number) { - this.fadeActiveTimer[channelIndex] = setTimeout( ()=>{ - store.dispatch({ - type:FADE_ACTIVE, - channel: channelIndex, - active: false - }) - }, - state.settings[0].protocolLatency - ) - } - - fadeInOut (channelIndex: number, fadeTime: number){ - let faderIndex = state.channels[0].channel[channelIndex].assignedFader - if (!state.faders[0].fader[faderIndex].pgmOn - && !state.faders[0].fader[faderIndex].voOn - && state.channels[0].channel[channelIndex].outputLevel === 0 - ) { - return - } - //Clear Old timer or set Fade to active: - if (state.channels[0].channel[channelIndex].fadeActive) { - clearInterval(this.fadeActiveTimer[channelIndex]); - this.clearTimer(channelIndex) - } - store.dispatch({ - type:FADE_ACTIVE, - channel: channelIndex, - active: true - }); - - if (state.faders[0].fader[faderIndex].pgmOn || state.faders[0].fader[faderIndex].voOn) { - this.fadeUp(channelIndex, fadeTime, faderIndex); - } else { - this.fadeDown(channelIndex, fadeTime); - } - } - - fadeUp(channelIndex: number, fadeTime: number, faderIndex: number) { - let outputLevel = state.channels[0].channel[channelIndex].outputLevel; - let targetVal = state.faders[0].fader[faderIndex].faderLevel; - - if (state.faders[0].fader[faderIndex].voOn) { - targetVal = targetVal * (100-state.settings[0].voLevel)/100 - } - const step: number = (targetVal-outputLevel)/(fadeTime/FADE_INOUT_SPEED); - const dispatchResolution: number = FADE_DISPATCH_RESOLUTION*step; - let dispatchTrigger: number = 0; - this.clearTimer(channelIndex) - - if (targetVal { - outputLevel += step; - dispatchTrigger += step; - - if (dispatchTrigger > dispatchResolution) { - this.mixerConnection.updateFadeIOLevel(channelIndex, outputLevel); - store.dispatch({ - type:SET_OUTPUT_LEVEL, - channel: channelIndex, - level: outputLevel - }); - dispatchTrigger = 0; - } - - if ( outputLevel <= targetVal){ - outputLevel = targetVal; - this.mixerConnection.updateFadeIOLevel(channelIndex, outputLevel); - this.clearTimer(channelIndex) - - store.dispatch({ - type:SET_OUTPUT_LEVEL, - channel: channelIndex, - level: outputLevel - }); - this.delayedFadeActiveDisable(channelIndex); - return true; - } - }, FADE_INOUT_SPEED); - } else { - this.timer[channelIndex] = setInterval(() => { - outputLevel += step; - dispatchTrigger += step; - this.mixerConnection.updateFadeIOLevel(channelIndex, outputLevel); - - if (dispatchTrigger > dispatchResolution) { - store.dispatch({ - type:SET_OUTPUT_LEVEL, - channel: channelIndex, - level: outputLevel - }); - dispatchTrigger = 0; - } - - - if ( outputLevel >= targetVal ) { - outputLevel = targetVal; - this.mixerConnection.updateFadeIOLevel(channelIndex, outputLevel); - this.clearTimer(channelIndex) - store.dispatch({ - type:SET_OUTPUT_LEVEL, - channel: channelIndex, - level: outputLevel - }); - this.delayedFadeActiveDisable(channelIndex); - return true; - } - - }, FADE_INOUT_SPEED); - } - } - - fadeDown(channelIndex: number, fadeTime: number) { - let outputLevel = state.channels[0].channel[channelIndex].outputLevel; - const min = this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_OUT_GAIN[0].min; - const step = (outputLevel-min)/(fadeTime/FADE_INOUT_SPEED); - const dispatchResolution: number = FADE_DISPATCH_RESOLUTION*step; - let dispatchTrigger: number = 0; - - this.clearTimer(channelIndex) - - this.timer[channelIndex] = setInterval(() => { - outputLevel -= step; - dispatchTrigger += step; - this.mixerConnection.updateFadeIOLevel(channelIndex, outputLevel); - - if (dispatchTrigger > dispatchResolution) { - store.dispatch({ - type:SET_OUTPUT_LEVEL, - channel: channelIndex, - level: outputLevel - }); - dispatchTrigger = 0; - } - - if ( outputLevel <= min ){ - outputLevel=min; - this.mixerConnection.updateFadeIOLevel(channelIndex, outputLevel); - this.clearTimer(channelIndex) - store.dispatch({ - type:SET_OUTPUT_LEVEL, - channel: channelIndex, - level: outputLevel - }); - this.delayedFadeActiveDisable(channelIndex); - return true; - } - - }, FADE_INOUT_SPEED); - } -} diff --git a/server/utils/SettingsStorage.ts b/server/utils/SettingsStorage.ts deleted file mode 100644 index c4695d1f..00000000 --- a/server/utils/SettingsStorage.ts +++ /dev/null @@ -1,134 +0,0 @@ -// Node Modules: -const fs = require('fs') -const path = require('path') -import { store, state } from '../reducers/store' - - -// Redux: -import { SET_COMPLETE_CH_STATE } from '../reducers/channelActions' -import { SET_COMPLETE_FADER_STATE } from '../reducers/faderActions' -import { logger } from './logger' - - -export const loadSettings = (storeRedux: any) => { - let settingsInterface = storeRedux.settings[0]; - try { - return (JSON.parse(fs.readFileSync(path.resolve('storage', 'settings.json')))) - } - catch (error) { - logger.error('Couldn´t read Settings.json file, creating af new', {}) - saveSettings(settingsInterface); - return (settingsInterface); - } -}; - -export const saveSettings = (settings: any) => { - let json = JSON.stringify(settings); - if (!fs.existsSync('storage')){ - fs.mkdirSync('storage'); - } - fs.writeFile(path.resolve('storage', 'settings.json'), json, 'utf8', (error: any)=>{ - logger.error('Error writing settings.json file: ', error); - }); -}; - - -export const loadSnapshotState = (stateSnapshot: any, stateChannelSnapshot: any, numberOfChannels: Array, numberOfFaders: number, fileName: string, loadAll: boolean) => { - try { - const stateFromFile = JSON.parse(fs.readFileSync(fileName)); - - if (loadAll) { - store.dispatch({ - type: SET_COMPLETE_CH_STATE, - allState: stateFromFile.channelState, - numberOfTypeChannels: numberOfChannels - }); - store.dispatch({ - type:SET_COMPLETE_FADER_STATE, - allState: stateFromFile.faderState, - numberOfTypeChannels: numberOfFaders - }); - } else { - stateChannelSnapshot.channel = stateChannelSnapshot.channel.map((channel: any, index: number) => { - if (stateFromFile.channelState.channel[index].assignedFader >= 0) { - channel.auxLevel = stateFromFile.channelState.channel[index].auxLevel || [] - channel.assignedFader = stateFromFile.channelState.channel[index].assignedFader - } else { - channel.assignedFader = -1 - } - return channel - }) - - stateSnapshot.fader = stateSnapshot.fader.map((fader: any, index: number) => { - fader.monitor = stateFromFile.faderState.fader[index].monitor || -1 - return fader - }) - store.dispatch({ - type:SET_COMPLETE_CH_STATE, - allState: stateChannelSnapshot, - numberOfTypeChannels: numberOfChannels - }); - store.dispatch({ - type: SET_COMPLETE_FADER_STATE, - allState: stateSnapshot, - numberOfTypeChannels: numberOfFaders - }); - - } - - } - catch (error) { - logger.error("Error loading Snapshot" + String(error), {}) - } -}; - -export const saveSnapshotState = (stateSnapshot: any, fileName: string) => { - let json = JSON.stringify(stateSnapshot); - fs.writeFile(fileName, json, 'utf8', (error: any)=>{ - if (error) { - logger.error("Error saving Snapshot" + String(error), {}) - } else { - logger.verbose('Snapshot ' + fileName + ' Saved to storage folder', {}) - } - }); -} - -export const getSnapShotList = () => { - const files = fs.readdirSync(path.resolve('storage')).filter((file: string) => { - if (file.includes('.shot') && file !== 'default.shot') { - return true - } - }) - return files -} - -export const getCcgSettingsList = () => { - const files = fs.readdirSync(path.resolve('storage')).filter((file: string) => { - if (file.includes('.ccg') && file !== 'default-casparcg.ccg') { - return true - } - }) - return files -} - -export const setCcgDefault = (fileName: string) => { - let data: any - try { - data = fs.readFileSync(path.join('storage', fileName)) - } - catch (error) { - logger.error('Couldn´t read ' + fileName + ' file', {}) - return - } - - const defaultFile = path.join('storage', 'default-casparcg.ccg') - fs.writeFile(defaultFile, data, 'utf8', (error: any)=>{ - if (error) { - logger.error("Error setting default CasparCG setting" + String(error), {}) - } else { - logger.info('CasparCG' + fileName + ' Saved as default CasparCG', {}) - } - }); - - -} diff --git a/server/utils/SnapshotHandler.ts b/server/utils/SnapshotHandler.ts deleted file mode 100644 index 6607c492..00000000 --- a/server/utils/SnapshotHandler.ts +++ /dev/null @@ -1,60 +0,0 @@ -//Utils: -import { loadSnapshotState, saveSnapshotState } from './SettingsStorage'; -import { - mixerProtocolPresets, -} from '../mainClasses' -import { state } from '../reducers/store' -import { logger } from './logger'; - -const path = require('path') -export class SnapshotHandler { - numberOfChannels: number[] = [] - settingsPath: string = '' - - constructor() { - logger.info('SETTINGS UP STATE', {}) - - this.snapShopStoreTimer(); - - // Count total number of channels: - mixerProtocolPresets[state.settings[0].mixerProtocol].channelTypes.forEach((item: any, index: number) => { - this.numberOfChannels.push(state.settings[0].numberOfChannelsInType[index]); - }); - this.loadSnapshotSettings(path.resolve('storage', 'default.shot'), true) - - // ** UNCOMMENT TO DUMP A FULL STORE: - //const fs = require('fs') - //fs.writeFileSync('src/components/__tests__/__mocks__/parsedFullStore-UPDATE.json', JSON.stringify(global.storeRedux.getState())) - - } - - snapShopStoreTimer() { - const saveTimer = setInterval(() => { - let snapshot = { - faderState: state.faders[0], - channelState: state.channels[0] - } - saveSnapshotState(snapshot, path.resolve(this.settingsPath, 'storage', 'default.shot')) - }, - 2000); - } - - loadSnapshotSettings(fileName: string, loadAll: boolean) { - loadSnapshotState( - state.faders[0], - state.channels[0], - this.numberOfChannels, - state.settings[0].numberOfFaders, - fileName, - loadAll - ); - } - - saveSnapshotSettings(fileName: string) { - let snapshot = { - faderState: state.faders[0], - channelState: state.channels[0] - } - saveSnapshotState(snapshot, fileName); - } -} \ No newline at end of file diff --git a/server/utils/logger.ts b/server/utils/logger.ts deleted file mode 100644 index b24b7791..00000000 --- a/server/utils/logger.ts +++ /dev/null @@ -1,36 +0,0 @@ -const winston = require('winston') -const Elasticsearch = require('winston-elasticsearch') -const processArgs = require('minimist')(process.argv.slice(2)) - -const loggerIp = process.env.loggerIp || processArgs.loggerIp || "0.0.0.0" -const loggerPort = process.env.loggerPort || processArgs.loggerPort || 9200 -const loggerLevel = process.env.loggerLevel || processArgs.loggerLevel || 'info' -const loggerFileLevel = process.env.loggerFileLevel || processArgs.loggerFileLevel || 'error' -const loggerConsoleLevel = process.env.loggerConsoleLevel || processArgs.loggerConsoleLevel || 'error' - -console.log('Elastic Ip :', loggerIp) -console.log('Elastic Port :', loggerPort) - -const esTransportOpts = { - level: loggerLevel, - indexPrefix: 'sisyfos', - clientOpts: { node: 'http://'+ loggerIp + ':' + String(loggerPort) } -}; - -const logger = winston.createLogger({ - level: 'info', - format: winston.format.json(), - transports: [ - new winston.transports.File({ filename: "logfile.log", level: loggerFileLevel }), //save errors on file - new winston.transports.Console({ level: loggerConsoleLevel }), //save errors on file - new Elasticsearch(esTransportOpts) //everything info and above goes to elastic - ] -}) - -if (process.env.NODE_ENV !== 'production') { - logger.add(new winston.transports.Console({ //we also log to console if we're not in production - format: winston.format.simple() - })) -} - -export { logger } \ No newline at end of file diff --git a/server/utils/mixerConnections/CasparCGConnection.ts b/server/utils/mixerConnections/CasparCGConnection.ts deleted file mode 100644 index 17702a4b..00000000 --- a/server/utils/mixerConnections/CasparCGConnection.ts +++ /dev/null @@ -1,374 +0,0 @@ -//Node Modules: -const osc = require('osc') -const fs = require('fs') -import * as path from 'path'; -import { CasparCG } from 'casparcg-connection' - -//Utils: -import { store, state } from '../../reducers/store' -import { ICasparCGMixerGeometry, ICasparCGChannelLayerPair, ICasparCGMixerGeometryFile } from '../../constants/MixerProtocolInterface'; -import { IChannel } from '../../reducers/channelsReducer'; -import { SET_PRIVATE } from '../../reducers/channelActions' -import { SET_VU_LEVEL, SET_CHANNEL_LABEL } from '../../reducers/faderActions' -import { logger } from '../logger' - -interface CommandChannelMap { - [key: string]: number -} - -interface ICasparCGChannel extends IChannel { - producer?: string - source?: string -} - -const OSC_PATH_PRODUCER = /\/channel\/(\d+)\/stage\/layer\/(\d+)\/producer\/type/ -const OSC_PATH_PRODUCER_FILE_NAME = /\/channel\/(\d+)\/stage\/layer\/(\d+)\/file\/path/ -const OSC_PATH_PRODUCER_CHANNEL_LAYOUT = /\/channel\/(\d+)\/stage\/layer\/(\d+)\/producer\/channel_layout/ - -export class CasparCGConnection { - mixerProtocol: ICasparCGMixerGeometry; - connection: any; - oscClient: any; - oscCommandMap: { [key: string]: CommandChannelMap } = {}; - - constructor(mixerProtocol: ICasparCGMixerGeometry) { - - this.mixerProtocol = mixerProtocol - this.injectCasparCGSetting() - - this.connection = new CasparCG({ - autoReconnect: true, - autoReconnectAttempts: 20, - autoReconnectInterval: 3000, - host: state.settings[0].deviceIp, - port: parseInt(state.settings[0].devicePort + ''), - }) - logger.info("Trying to connect to CasparCG...") - this.connection.onConnected = () => { - logger.info("CasparCG connected"); - this.setupMixerConnection(); - } - this.connection.onDisconnected = () => { - logger.info("CasparCG disconnected"); - } - this.connection.connect(); - - this.oscCommandMap.CHANNEL_VU = {} - this.mixerProtocol.fromMixer.CHANNEL_VU.forEach((paths, index) => { - this.oscCommandMap.CHANNEL_VU[paths[0]] = index - }) - } - - injectCasparCGSetting() { - const geometryFile = path.join('storage', 'default-casparcg.ccg'); - - let geometry: ICasparCGMixerGeometryFile | undefined - try { - let inputObj = JSON.parse(fs.readFileSync(geometryFile, { - encoding: 'utf-8' - })) - if (inputObj.toMixer && inputObj.toMixer.PGM_CHANNEL_FADER_LEVEL) { - geometry = inputObj - } - } catch (e) { - // Handling a file should be removed from Constants in the future: - logger.info('CasparCG Audio geometry file has not been created') - } - if (geometry) { - this.mixerProtocol.fromMixer = geometry.fromMixer || this.mixerProtocol.fromMixer - this.mixerProtocol.toMixer = geometry.toMixer || this.mixerProtocol.toMixer - this.mixerProtocol.channelLabels = geometry.channelLabels || this.mixerProtocol.channelLabels - this.mixerProtocol.sourceOptions = geometry.sourceOptions || this.mixerProtocol.sourceOptions - } - } - - setupMixerConnection() { - if (!this.oscClient) { - const remotePort = parseInt(state.settings[0].devicePort + '') + 1000 - this.oscClient = new osc.UDPPort({ - localAddress: state.settings[0].localIp, - localPort: remotePort, - remoteAddress: state.settings[0].deviceIp, - remotePort - }) - .on('ready', () => { - logger.info("Receiving state of mixer"); - }) - .on('message', (message: any) => { - const index = this.checkOscCommand(message.address, this.oscCommandMap.CHANNEL_VU) - if (index !== undefined && message.args) { - store.dispatch({ - type: SET_VU_LEVEL, - channel: index, - // CCG returns "produced" audio levels, before the Volume mixer transform - // We therefore want to premultiply this to show useful information about audio levels - level: Math.min(1, message.args[0] * state.faders[0].fader[index].faderLevel) - }); - } else if (this.mixerProtocol.sourceOptions) { - const m = message.address.split('/'); - - if (m[1] === 'channel' && m[6] === 'producer' && m[7] === 'type') { - const index = this.mixerProtocol.sourceOptions.sources.findIndex(i => i.channel === parseInt(m[2], 10) && i.layer === parseInt(m[5])) - if (index >= 0) { - store.dispatch({ - type: SET_PRIVATE, - channel: index, - tag: 'producer', - value: message.args[0] - }) - } - } else if (m[1] === 'channel' && m[6] === 'producer' && m[7] === 'channel_layout') { - const index = this.mixerProtocol.sourceOptions.sources.findIndex(i => i.channel === parseInt(m[2], 10) && i.layer === parseInt(m[5])) - if (index >= 0) { - store.dispatch({ - type: SET_PRIVATE, - channel: index, - tag: 'channel_layout', - value: message.args[0] - }) - } - } else if (m[1] === 'channel' && m[6] === 'file' && m[7] === 'path') { - const index = this.mixerProtocol.sourceOptions.sources.findIndex(i => i.channel === parseInt(m[2], 10) && i.layer === parseInt(m[5])) - if (index >= 0) { - store.dispatch({ - type: SET_PRIVATE, - channel: index, - tag: 'file_path', - value: message.args[0].low - }) - } - } - } - }) - .on('error', (error: any) => { - logger.error("Error : " + JSON.stringify(error)); - logger.info("Lost OSC connection"); - }); - - this.oscClient.open(); - logger.info("Listening for status on CasparCG: " + state.settings[0].deviceIp + ':' + remotePort) - } - - // Restore mixer values to the ones we have internally - state.faders[0].fader.forEach((channel, index) => { - this.updateFadeIOLevel(index, channel.faderLevel); - this.updatePflState(index); - }) - - // Set source labels from geometry definition - if (this.mixerProtocol.channelLabels) { - this.mixerProtocol.channelLabels.forEach((label, channelIndex) => { - store.dispatch({ - type: SET_CHANNEL_LABEL, - channel: channelIndex, - label - }); - }); - } - } - - checkOscCommand(address: string, commandSpace: CommandChannelMap): number | undefined { - const index = commandSpace[address] - if (index !== undefined) { - return index - } - return undefined - } - - findChannelIndex(channel: number, layer: number, channelLayerPairs: Array, matchFirst?: boolean): number { - return channelLayerPairs.findIndex((i) => { - if (matchFirst) { - return (i[0].channel === channel && i[0].layer === layer) - } - return !!i.find(j => j.channel === channel && j.layer === layer) - }) - } - - pingMixerCommand = () => { - //Ping OSC mixer if mixerProtocol needs it. - /* this.mixerProtocol.pingCommand.map((command) => { - this.sendOutMessage( - command.mixerMessage, - 0, - command.value - ); - }); */ - } - - private syncCommand = Promise.resolve() - controlVolume = (channel: number, layer: number, value: number) => { - this.syncCommand = this.syncCommand.then(() => - this.connection.mixerVolume(channel, layer, value, 0, undefined).catch((e: any) => { - logger.error('Failed to send command' + JSON.stringify(e)) - }) - ).then(() => { }) - } - - controlChannelSetting = (channel: number, layer: number, producer: string, file: string, setting: string, value: string) => { - this.connection.stop(channel, layer) - .then(() => { - if (setting === 'CHANNEL_LAYOUT') { - switch (producer) { - case 'ffmpeg': - return this.connection.play( - channel, - layer, - file, - true, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - value); - case 'decklink': - return this.connection.playDecklink( - channel, - layer, - parseInt(file, 10), - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - value); - } - } - return Promise.reject('Unknown operation'); - }).then(() => { - - }).catch((e: any) => { - logger.error('Failed to change channel setting' + JSON.stringify(e)) - }) - } - - setAllLayers = (pairs: ICasparCGChannelLayerPair[], value: number) => { - pairs.forEach((i) => { - this.controlVolume(i.channel, i.layer, value); - }) - } - - updateChannelSetting(channelIndex: number, setting: string, value: string) { - if (this.mixerProtocol.sourceOptions && state.channels[0].channel[channelIndex].private) { - const pair = this.mixerProtocol.sourceOptions.sources[channelIndex]; - const producer = state.channels[0].channel[channelIndex].private!['producer']; - let filePath = String(state.channels[0].channel[channelIndex].private!['file_path']); - filePath = filePath.replace(/\.[\w\d]+$/, '') - this.controlChannelSetting(pair.channel, pair.layer, producer, filePath, setting, value); - } - } - - updatePflState(channelIndex: number) { - if (channelIndex > this.mixerProtocol.toMixer.PGM_CHANNEL_FADER_LEVEL.length - 1) { - return - } - - if (state.faders[0].fader[channelIndex].pflOn === true) { - // Enable SOLO on this channel on MONITOR - const pairs = this.mixerProtocol.toMixer.MONITOR_CHANNEL_FADER_LEVEL[channelIndex]; - this.setAllLayers(pairs, state.faders[0].fader[channelIndex].faderLevel); - - // Ensure that all other non-SOLO channels are muted on MONITOR - const others = state.faders[0].fader - .map((i, index) => i.pflOn ? undefined : index) - .filter(i => ( - i !== undefined && - i < this.mixerProtocol.toMixer.MONITOR_CHANNEL_FADER_LEVEL.length - )) as number[] - others.forEach(i => { - const pairs = this.mixerProtocol.toMixer.MONITOR_CHANNEL_FADER_LEVEL[i]; - this.setAllLayers(pairs, this.mixerProtocol.fader.min); - }) - } else { - // check if any other channels are SOLO - const others = state.faders[0].fader - .map((i, index) => i.pflOn ? index : undefined) - .filter(i => ( - i !== undefined && - i < this.mixerProtocol.toMixer.MONITOR_CHANNEL_FADER_LEVEL.length - )) as number[] - - if (others.length > 0) { - // other channels are SOLO, mute this channel on MONITOR - const pairs = this.mixerProtocol.toMixer.MONITOR_CHANNEL_FADER_LEVEL[channelIndex]; - this.setAllLayers(pairs, this.mixerProtocol.fader.min); - } else { - // There are no other SOLO channels, restore MONITOR to match PGM - state.channels[0].channel.forEach((i, index) => { - if (index > this.mixerProtocol.toMixer.MONITOR_CHANNEL_FADER_LEVEL.length - 1) { - return - } - - const pairs = this.mixerProtocol.toMixer.MONITOR_CHANNEL_FADER_LEVEL[index]; - this.setAllLayers(pairs, state.channels[0].channel[index].outputLevel); - }) - } - } - } - - updateMuteState(channelIndex: number, muteOn: boolean) { - return true - } - - updateNextAux(channelIndex: number, level: number) { - return true - } - - updateThreshold(channelIndex: number, level: number) { - return true - } - updateRatio(channelIndex: number, level: number) { - return true - } - updateDelayTime(channelIndex: number, level: number) { - return true - } - updateLow(channelIndex: number, level: number) { - return true - } - updateLoMid(channelIndex: number, level: number) { - return true - } - updateMid(channelIndex: number, level: number) { - return true - } - updateHigh(channelIndex: number, level: number) { - return true - } - updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { - return true - } - - updateFadeIOLevel(channelIndex: number, outputLevel: number) { - if (channelIndex > this.mixerProtocol.toMixer.PGM_CHANNEL_FADER_LEVEL.length - 1) { - return - } - - const pgmPairs = this.mixerProtocol.toMixer.PGM_CHANNEL_FADER_LEVEL[channelIndex] - this.setAllLayers(pgmPairs, outputLevel) - - const anyPflOn = state.faders[0].fader.reduce((memo, i) => memo || i.pflOn, false) - // Check if there are no SOLO channels on MONITOR or there are, but this channel is SOLO - if (!anyPflOn || (anyPflOn && state.faders[0].fader[channelIndex].pflOn)) { - const pairs = this.mixerProtocol.toMixer.MONITOR_CHANNEL_FADER_LEVEL[channelIndex]; - if (state.faders[0].fader[channelIndex].pflOn) { - this.setAllLayers(pairs, state.faders[0].fader[channelIndex].faderLevel); - } else { - this.setAllLayers(pairs, outputLevel); - } - } - } - - updateChannelName(channelIndex: number) { - //CasparCG does not need Labels. - } - - injectCommand(command: string[]) { - this.connection.createCommand(command[0]) - } -} - diff --git a/server/utils/mixerConnections/EmberMixerConnection.ts b/server/utils/mixerConnections/EmberMixerConnection.ts deleted file mode 100644 index cdd1d2c4..00000000 --- a/server/utils/mixerConnections/EmberMixerConnection.ts +++ /dev/null @@ -1,288 +0,0 @@ -//@ts-ignore -import { DeviceTree, Ember} from 'emberplus' -import { store, state } from '../../reducers/store' -import { huiRemoteConnection } from '../../mainClasses' - -//Utils: -import { IMixerProtocol } from '../../constants/MixerProtocolInterface'; -import { - SET_FADER_LEVEL, - SET_CHANNEL_LABEL -} from '../../reducers/faderActions' -import { logger } from '../logger'; - - -export class EmberMixerConnection { - mixerProtocol: IMixerProtocol; - emberConnection: any; - deviceRoot: any; - emberNodeObject: Array; - - - constructor(mixerProtocol: IMixerProtocol) { - this.sendOutMessage = this.sendOutMessage.bind(this); - this.pingMixerCommand = this.pingMixerCommand.bind(this); - - this.emberNodeObject = new Array(200); - this.mixerProtocol = mixerProtocol; - - logger.info("Setting up Ember connection") - this.emberConnection = new DeviceTree( - state.settings[0].deviceIp, - state.settings[0].devicePort - ); - - this.emberConnection.on('error', (error: any) => { - if ( - (error.message + '').match(/econnrefused/i) || - (error.message + '').match(/disconnected/i) - ) { - logger.error('Ember connection not establised') - } else { - logger.error('Ember connection unknown error' + error.message) - } - }) - this.emberConnection.on('connected', () => { - logger.info('Ember connected') - let deviceRoot: any; - this.emberConnection.connect() - .then(() => { - console.log("Getting Directory") - return this.emberConnection.getDirectory(); - }) - .then((r: any) => { - console.log("Directory :", r); - this.deviceRoot = r; - this.emberConnection.expand(r.elements[0]) - .then(() => { - this.setupMixerConnection(); - }) - }) - .catch((e: any) => { - console.log(e.stack); - }); - }) - this.emberConnection.on('disconnected', () => { - logger.error('Lost Ember connection') - }) - - } - - setupMixerConnection() { - - let ch: number = 1; - state.settings[0].numberOfChannelsInType.forEach((numberOfChannels, typeIndex) => { - for (let channelTypeIndex=0; channelTypeIndex < numberOfChannels ; channelTypeIndex++) { - this.subscribeFaderLevel(ch, typeIndex, channelTypeIndex); - ch++; - } - }) - - ch = 1; - state.settings[0].numberOfChannelsInType.forEach((numberOfChannels, typeIndex) => { - for (let channelTypeIndex=0; channelTypeIndex < numberOfChannels ; channelTypeIndex++) { - this.subscribeChannelName(ch, typeIndex, channelTypeIndex); - ch++; - } - }) - -/* - .CHANNEL_VU)){ - store.dispatch({ - type:SET_VU_LEVEL, - channel: ch - 1, - level: message.args[0] - }); - */ - this.emberConnection - .on('error', (error: any) => { - console.log("Error : ", error); - console.log("Lost EMBER connection"); - }); - - //Ping OSC mixer if mixerProtocol needs it. - if (this.mixerProtocol.pingTime > 0) { - let emberTimer = setInterval( - () => { - this.pingMixerCommand(); - }, - this.mixerProtocol.pingTime - ); - } - } - - subscribeFaderLevel(ch: number, typeIndex: number, channelTypeIndex: number) { - this.emberConnection.getNodeByPath(this.mixerProtocol.channelTypes[typeIndex].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage.replace("{channel}", String(channelTypeIndex+1))) - .then((node: any) => { - this.emberNodeObject[ch-1] = node; - this.emberConnection.subscribe(node, (() => { - if (!state.channels[0].channel[ch-1].fadeActive - && !state.channels[0].channel[ch - 1].fadeActive - && node.contents.value > this.mixerProtocol.channelTypes[typeIndex].fromMixer.CHANNEL_OUT_GAIN[0].min) { - store.dispatch({ - type: SET_FADER_LEVEL, - channel: ch-1, - level: node.contents.value - }); - if (huiRemoteConnection) { - huiRemoteConnection.updateRemoteFaderState(ch-1, node.contents.value); - } - } - - }) - ) - }) - } - - subscribeChannelName(ch: number, typeIndex: number, channelTypeIndex: number) { - this.emberConnection.getNodeByPath(this.mixerProtocol.channelTypes[typeIndex].fromMixer.CHANNEL_NAME[0].mixerMessage.replace("{channel}", String(channelTypeIndex+1))) - .then((node: any) => { - this.emberConnection.subscribe(node, (() => { - store.dispatch({ - type: SET_CHANNEL_LABEL, - channel: ch-1, - level: node.contents.value - }); - }) - ) - }) - } - - pingMixerCommand() { - //Ping Ember mixer if mixerProtocol needs it. - return; - this.mixerProtocol.pingCommand.map((command) => { - this.sendOutMessage( - command.mixerMessage, - 0, - command.value, - command.type - ); - }); - } - - sendOutMessage(mixerMessage: string, channel: number, value: string | number, type: string) { - let channelString = this.mixerProtocol.leadingZeros ? ("0"+channel).slice(-2) : channel.toString(); - -// this.emberConnection.QualifiedParameter.setValue("1.1.1.1.1.1", 21) -// this.emberConnection.getNodeByPath(message) -// .then((response: any) => { -// console.log("Node object :", response) - this.emberConnection.setValue( - mixerMessage, - typeof value === 'number' ? value : parseFloat(value) - ) -// }) - } - - sendOutRequest(mixerMessage: string, channel: number) { - let channelString = this.mixerProtocol.leadingZeros ? ("0"+channel).slice(-2) : channel.toString(); - let message = mixerMessage.replace( - "{channel}", - channelString - ); - if (message != 'none') { -/* - this.oscConnection.send({ - address: message - }); -*/ - } - } - - updateOutLevel(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - this.sendOutMessage( - this.emberNodeObject[channelIndex], - channelTypeIndex+1, - state.channels[0].channel[channelIndex].outputLevel, - "f" - ); - } - - updatePflState(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - - if (state.faders[0].fader[channelIndex].pflOn === true) { - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].mixerMessage, - channelTypeIndex+1, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].value, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].type - ); - } else { - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].mixerMessage, - channelTypeIndex+1, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].value, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].type - ); - } - } - - updateMuteState(channelIndex: number, muteOn: boolean) { - return true - } - - updateNextAux(channelIndex: number, level: number) { - return true - } - - - updateThreshold(channelIndex: number, level: number) { - return true - } - updateRatio(channelIndex: number, level: number) { - return true - - } - updateDelayTime(channelIndex: number, level: number) { - return true - } - updateLow(channelIndex: number, level: number) { - return true - } - updateLoMid(channelIndex: number, level: number) { - return true - } - updateMid(channelIndex: number, level: number) { - return true - } - updateHigh(channelIndex: number, level: number) { - return true - } - updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { - return true - } - - updateFadeIOLevel(channelIndex: number, outputLevel: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - this.sendOutMessage( - this.emberNodeObject[channelIndex], - channelTypeIndex+1, - String(outputLevel), - "f" - ); - } - - updateChannelName(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let channelName = state.faders[0].fader[channelIndex].label; - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_NAME[0].mixerMessage, - channelTypeIndex+1, - channelName, - "string" - ); - } - - injectCommand(command: string[]) { - return true - } - -} - diff --git a/server/utils/mixerConnections/MidiMixerConnection.ts b/server/utils/mixerConnections/MidiMixerConnection.ts deleted file mode 100644 index 2a9e05ae..00000000 --- a/server/utils/mixerConnections/MidiMixerConnection.ts +++ /dev/null @@ -1,247 +0,0 @@ - -// *** Work around to run Web-midi on nodejs *** - - -// The `web-midi-api` module takes care of importing the `jazz-midi` module (which needs to be -// installed) and the WebMIDIAPI shim (which is already part of `web-midi-api`). -global.navigator = require('web-midi-api') -// WebMidi.js depends on the browser's performance.now() so we fake it with the `performance-now` -// Node module (which is installed as a dependency of `web-midi-api`). -if (!global.performance) global.performance = { now: require('performance-now') }; -//Node Modules: -const WebMidi = require('webmidi') - -import { store, state } from '../../reducers/store' -import { huiRemoteConnection } from '../../mainClasses' - - -//Utils: -import { MixerProtocolPresets } from '../../constants/MixerProtocolPresets'; -import { IMixerProtocol } from '../../constants/MixerProtocolInterface'; -import { SET_OUTPUT_LEVEL } from '../../reducers/channelActions' -import { - SET_VU_LEVEL, - SET_FADER_LEVEL, - SET_CHANNEL_LABEL, - TOGGLE_PGM -} from '../../reducers/faderActions' - - -export class MidiMixerConnection { - store: any; - mixerProtocol: any; - midiInput: any; - midiOutput:any; - - constructor(mixerProtocol: IMixerProtocol) { - this.sendOutMessage = this.sendOutMessage.bind(this); - this.pingMixerCommand = this.pingMixerCommand.bind(this); - - this.mixerProtocol = mixerProtocol || MixerProtocolPresets.genericMidi; - - WebMidi.enable((err: any) => { - - if (err) { - console.log("WebMidi could not be enabled.", err); - } - console.log("Connecting Mixer Midi input on port :", state.settings[0].mixerMidiInputPort); - console.log("Connecting Mixer Midi output on port :", state.settings[0].mixerMidiOutputPort); - this.midiInput = WebMidi.getInputByName(state.settings[0].mixerMidiInputPort); - this.midiOutput = WebMidi.getOutputByName(state.settings[0].mixerMidiOutputPort); - - this.setupMixerConnection(); - }); - } - - setupMixerConnection() { - this.midiInput.addListener('controlchange', 1, - (message: any) => { - console.log("Received 'controlchange' message (" + message.data + ")."); - if (message.data[1] >= parseInt(this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage) - && message.data[1] <= parseInt(this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage) + 24) { - let ch = 1 + message.data[1] - parseInt(this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage) - let faderChannel = 1 + state.channels[0].channel[ch - 1].assignedFader - store.dispatch({ - type: SET_FADER_LEVEL, - channel: faderChannel - 1, - level: message.data[2] - }); - if (!state.faders[0].fader[faderChannel - 1].pgmOn) { - store.dispatch({ - type: TOGGLE_PGM, - channel: state.channels[0].channel[ch - 1].assignedFader -1 - }); - } - if (huiRemoteConnection) { - huiRemoteConnection.updateRemoteFaderState(faderChannel - 1, state.faders[0].fader[faderChannel - 1].faderLevel) - } - if (state.faders[0].fader[faderChannel - 1].pgmOn && this.mixerProtocol.mode === 'master') - { - state.channels[0].channel.map((channel: any, index: number) => { - if (channel.assignedFader === faderChannel - 1) { - this.updateOutLevel(index); - } - }) - } - } - } - ); - this.midiInput.addListener('noteon', "all", - (error: any) => { - console.log("Received 'noteon' message (" + error.note.name + error.note.octave + ")."); - } - ); -/* - if ( - this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_VU) - ) { - if (state.settings[0].mixerProtocol === 'behringer') { - behringerMeter(message.args); - } else { - let ch = message.address.split("/")[2]; - store.dispatch({ - type:SET_VU_LEVEL, - channel: ch - 1, - level: message.args[0] - }); - } - } - if ( - this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_NAME) - ) { - let ch = message.address.split("/")[2]; - store.dispatch({ - type: SET_CHANNEL_LABEL, - channel: ch - 1, - label: message.args[0] - }); - console.log("OSC message: ", message.address); - } -*/ -return true; - //Ping OSC mixer if mixerProtocol needs it. - if (this.mixerProtocol.pingTime > 0) { - let oscTimer = setInterval( - () => { - this.pingMixerCommand(); - }, - this.mixerProtocol.pingTime - ); - } - } - - pingMixerCommand() { - //Ping OSC mixer if mixerProtocol needs it. - this.mixerProtocol.pingCommand.map((command: any) => { - this.sendOutMessage( - command.mixerMessage, - 0, - command.value - ); - }); - } - - sendOutMessage(ctrlMessage: string, channel: number, value: string) { - if (ctrlMessage != "none" && 0 <= parseFloat(value) && parseFloat(value) <= 127) { - let ctrlMessageInt = (parseInt(ctrlMessage) + channel - 1) - this.midiOutput.sendControlChange(ctrlMessageInt, value, 1); - } - } - - updateOutLevel(channelIndex: number) { - let faderIndex = state.channels[0].channel[channelIndex].assignedFader; - if (state.faders[0].fader[faderIndex].pgmOn) { - store.dispatch({ - type:SET_OUTPUT_LEVEL, - channel: channelIndex, - level: state.faders[0].fader[faderIndex].faderLevel - }); - } - this.sendOutMessage( - this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_OUT_GAIN[0].mixerMessage, - channelIndex+1, - String(state.channels[0].channel[channelIndex].outputLevel) - ); - /* Client mode is disabled - this.sendOutMessage( - this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_FADER_LEVEL[0].mixerMessage, - channelIndex+1, - state.faders[0].fader[channelIndex].faderLevel - ); - */ - } - - updatePflState(channelIndex: number) { - - if (state.faders[0].fader[channelIndex].pflOn === true) { - this.sendOutMessage( - this.mixerProtocol.channelTypes[0].toMixer.PFL_ON[0].mixerMessage, - channelIndex+1, - this.mixerProtocol.channelTypes[0].toMixer.PFL_ON[0].value - ); - } else { - this.sendOutMessage( - this.mixerProtocol.channelTypes[0].toMixer.PFL_OFF[0].mixerMessage, - channelIndex+1, - this.mixerProtocol.channelTypes[0].toMixer.PFL_OFF[0].value - ); - } - } - - updateMuteState(channelIndex: number, muteOn: boolean) { - return true - } - - updateNextAux(channelIndex: number, level: number) { - return true - } - updateThreshold(channelIndex: number, level: number) { - return true - } - updateRatio(channelIndex: number, level: number) { - return true - - } - updateDelayTime(channelIndex: number, level: number) { - return true - } - updateLow(channelIndex: number, level: number) { - return true - } - updateLoMid(channelIndex: number, level: number) { - return true - } - updateMid(channelIndex: number, level: number) { - return true - } - updateHigh(channelIndex: number, level: number) { - return true - } - updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { - return true - } - - updateFadeIOLevel(channelIndex: number, outputLevel: number) { - this.sendOutMessage( - this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_OUT_GAIN[0].mixerMessage, - channelIndex+1, - String(outputLevel) - ); - } - - - updateChannelName(channelIndex: number) { - let channelName = state.faders[0].fader[channelIndex].label; - this.sendOutMessage( - this.mixerProtocol.channelTypes[0].toMixer.CHANNEL_NAME[0].mixerMessage, - channelIndex+1, - channelName - ); - } - - injectCommand(command: string[]) { - return true - } - -} - diff --git a/server/utils/mixerConnections/OscMixerConnection.ts b/server/utils/mixerConnections/OscMixerConnection.ts deleted file mode 100644 index 17e86975..00000000 --- a/server/utils/mixerConnections/OscMixerConnection.ts +++ /dev/null @@ -1,597 +0,0 @@ -//Node Modules: -const osc = require('osc') -import { store, state } from '../../reducers/store' -import { huiRemoteConnection } from '../../mainClasses' -import { socketServer } from '../../expressHandler' - - -//Utils: -import { IMixerProtocol } from '../../constants/MixerProtocolInterface' -import { behringerMeter } from './productSpecific/behringer' -import { midasMeter } from './productSpecific/midas' -import { SET_OUTPUT_LEVEL, SET_AUX_LEVEL } from '../../reducers/channelActions' -import { - SET_VU_LEVEL, - SET_FADER_LEVEL, - SET_CHANNEL_LABEL, - TOGGLE_PGM, - SET_FADER_THRESHOLD, - SET_FADER_RATIO, - SET_FADER_LO_MID, - SET_FADER_MID, - SET_FADER_HIGH, - SET_FADER_LOW, - SET_FADER_DELAY_TIME, - SET_MUTE -} from '../../reducers/faderActions' -import { SET_MIXER_ONLINE } from '../../reducers/settingsActions'; -import { SOCKET_SET_VU } from '../../constants/SOCKET_IO_DISPATCHERS'; -import { logger } from '../logger' - -export class OscMixerConnection { - mixerProtocol: IMixerProtocol; - cmdChannelIndex: number; - oscConnection: any; - mixerOnlineTimer: any; - - constructor(mixerProtocol: IMixerProtocol) { - this.sendOutMessage = this.sendOutMessage.bind(this); - this.pingMixerCommand = this.pingMixerCommand.bind(this); - - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: false - }); - - this.mixerProtocol = mixerProtocol; - - this.cmdChannelIndex = this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage.split('/').findIndex(ch => ch==='{channel}'); - - this.oscConnection = new osc.UDPPort({ - localAddress: state.settings[0].localIp, - localPort: parseInt(state.settings[0].localOscPort + ''), - remoteAddress: state.settings[0].deviceIp, - remotePort: parseInt(state.settings[0].devicePort + '') - }); - this.setupMixerConnection(); - } - - setupMixerConnection() { - this.oscConnection - .on("ready", () => { - logger.info("Receiving state of desk", {}) - this.initialCommands() - - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: true - }); - global.mainThreadHandler.updateFullClientStore() - }) - .on('message', (message: any) => { - clearTimeout(this.mixerOnlineTimer) - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: true - }); - logger.verbose("Received OSC message: " + message.address, {}) - if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .CHANNEL_VU[0].mixerMessage)){ - if (state.settings[0].mixerProtocol.includes('behringer')) { - behringerMeter(message.args); - } else if (state.settings[0].mixerProtocol.includes('midas')) { - midasMeter(message.args); - } else { - let ch = message.address.split("/")[this.cmdChannelIndex]; - store.dispatch({ - type:SET_VU_LEVEL, - channel: state.channels[0].channel[ch - 1].assignedFader, - level: message.args[0] - }); - socketServer.emit( - SOCKET_SET_VU, - { - faderIndex: state.channels[0].channel[ch - 1].assignedFader, - level: message.args[0] - } - ) - } - } else if ( this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .CHANNEL_OUT_GAIN[0].mixerMessage)){ - let ch = message.address.split("/")[this.cmdChannelIndex]; - let assignedFaderIndex = state.channels[0].channel[ch - 1].assignedFader - - - if (!state.channels[0].channel[ch - 1].fadeActive) - { - if (message.args[0] > this.mixerProtocol.fader.min + (this.mixerProtocol.fader.max * state.settings[0].autoResetLevel / 100)) { - store.dispatch({ - type: SET_FADER_LEVEL, - channel: assignedFaderIndex, - level: message.args[0] - }); - state.channels[0].channel.forEach((item, index) => { - if (item.assignedFader === assignedFaderIndex) { - store.dispatch({ - type: SET_OUTPUT_LEVEL, - channel: index, - level: message.args[0] - }); - } - }) - if (!state.faders[0].fader[assignedFaderIndex].pgmOn) { - if (message.args[0] > this.mixerProtocol.fader.min) { - store.dispatch({ - type: TOGGLE_PGM, - channel: assignedFaderIndex - }); - } - } - } else if (state.faders[0].fader[assignedFaderIndex].pgmOn - || state.faders[0].fader[assignedFaderIndex].voOn) - { - store.dispatch({ - type: SET_FADER_LEVEL, - channel: assignedFaderIndex, - level: message.args[0] - }); - state.channels[0].channel.forEach((item, index) => { - if (item.assignedFader === assignedFaderIndex) { - store.dispatch({ - type: SET_OUTPUT_LEVEL, - channel: index, - level: message.args[0] - }); - } - }) - } - global.mainThreadHandler.updatePartialStore(assignedFaderIndex) - - if (huiRemoteConnection) { - huiRemoteConnection.updateRemoteFaderState(assignedFaderIndex, message.args[0]); - } - } - } else if ( this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .AUX_LEVEL[0].mixerMessage)){ - - let commandArray: string[] = this.mixerProtocol.channelTypes[0].fromMixer - .AUX_LEVEL[0].mixerMessage.split('/') - let messageArray: string[] = message.address.split('/') - let ch = 0 - let auxIndex = 0 - - commandArray.forEach((commandPart: string, index: number) => { - if (commandPart === '{channel}') { - ch = parseFloat(messageArray[index]) - } else if (commandPart === '{argument}') { - auxIndex = parseFloat(messageArray[index]) - 1 - } - }) - logger.verbose('Aux Message Channel : ' + ch + ' Aux Index :' + auxIndex + ' Level : ' + message.args[0]) - store.dispatch({ - type: SET_AUX_LEVEL, - channel: ch - 1, - auxIndex: auxIndex, - level: message.args[0] - }); - global.mainThreadHandler.updateFullClientStore() - - } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .CHANNEL_NAME[0].mixerMessage)) { - let ch = message.address.split("/")[this.cmdChannelIndex]; - store.dispatch({ - type: SET_CHANNEL_LABEL, - channel: state.channels[0].channel[ch - 1].assignedFader, - label: message.args[0] - }); - global.mainThreadHandler.updatePartialStore(state.channels[0].channel[ch - 1].assignedFader) - } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .CHANNEL_MUTE_ON[0].mixerMessage)) { - let ch = message.address.split("/")[this.cmdChannelIndex] - let mute = (message.args[0] === 0) ? 1 : 0 - store.dispatch({ - type: SET_MUTE, - channel: state.channels[0].channel[ch - 1].assignedFader, - muteOn: mute - }); - global.mainThreadHandler.updatePartialStore(state.channels[0].channel[ch - 1].assignedFader) - } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .THRESHOLD[0].mixerMessage)) { - let ch = message.address.split("/")[this.cmdChannelIndex]; - store.dispatch({ - type: SET_FADER_THRESHOLD, - channel: state.channels[0].channel[ch - 1].assignedFader, - level: message.args[0] - }); - global.mainThreadHandler.updatePartialStore(state.channels[0].channel[ch - 1].assignedFader) - } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .RATIO[0].mixerMessage)) { - let ch = message.address.split("/")[this.cmdChannelIndex] - let ratio = this.mixerProtocol.channelTypes[0].fromMixer.RATIO[0] - let level = message.args[0] / ((ratio.max-ratio.min) + ratio.min) - store.dispatch({ - type: SET_FADER_RATIO, - channel: state.channels[0].channel[ch - 1].assignedFader, - level: level - }) - global.mainThreadHandler.updatePartialStore(state.channels[0].channel[ch - 1].assignedFader) - } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .DELAY_TIME[0].mixerMessage)) { - let ch = message.address.split("/")[this.cmdChannelIndex] - let delay = this.mixerProtocol.channelTypes[0].fromMixer.DELAY_TIME[0] - let delayTime = message.args[0] / ((delay.max-delay.min) + delay.min) - store.dispatch({ - type: SET_FADER_DELAY_TIME, - channel: state.channels[0].channel[ch - 1].assignedFader, - delayTime: delayTime - }) - global.mainThreadHandler.updatePartialStore(state.channels[0].channel[ch - 1].assignedFader) - } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .LOW[0].mixerMessage)) { - let ch = message.address.split("/")[this.cmdChannelIndex]; - store.dispatch({ - type: SET_FADER_LOW, - channel: state.channels[0].channel[ch - 1].assignedFader, - level: message.args[0] - }); - global.mainThreadHandler.updatePartialStore(state.channels[0].channel[ch - 1].assignedFader) - } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .LO_MID[0].mixerMessage)) { - let ch = message.address.split("/")[this.cmdChannelIndex]; - store.dispatch({ - type: SET_FADER_LO_MID, - channel: state.channels[0].channel[ch - 1].assignedFader, - level: message.args[0] - }); - global.mainThreadHandler.updatePartialStore(state.channels[0].channel[ch - 1].assignedFader) - } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .MID[0].mixerMessage)) { - let ch = message.address.split("/")[this.cmdChannelIndex]; - store.dispatch({ - type: SET_FADER_MID, - channel: state.channels[0].channel[ch - 1].assignedFader, - level: message.args[0] - }); - global.mainThreadHandler.updatePartialStore(state.channels[0].channel[ch - 1].assignedFader) - } else if (this.checkOscCommand(message.address, this.mixerProtocol.channelTypes[0].fromMixer - .HIGH[0].mixerMessage)) { - let ch = message.address.split("/")[this.cmdChannelIndex]; - store.dispatch({ - type: SET_FADER_HIGH, - channel: state.channels[0].channel[ch - 1].assignedFader, - level: message.args[0] - }); - global.mainThreadHandler.updatePartialStore(state.channels[0].channel[ch - 1].assignedFader) - } else { - logger.verbose("Unknown OSC message: " + message.address, {}) - } - }) - .on('error', (error: any) => { - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: false - }); - global.mainThreadHandler.updateFullClientStore() - logger.error("Error : " + String(error), {}) - logger.info("Lost OSC connection", {}) - }); - - this.oscConnection.open(); - logger.info(`OSC listening on port ` + String(state.settings[0].localOscPort ), {}) - - //Ping OSC mixer if mixerProtocol needs it. - if (this.mixerProtocol.pingTime > 0) { - let oscTimer = setInterval( - () => { - this.pingMixerCommand(); - }, - this.mixerProtocol.pingTime - ); - } - } - - initialCommands() { - this.mixerProtocol.initializeCommands.forEach((item, itemIndex: number) => { - setTimeout(() => { - if (item.mixerMessage.includes("{channel}")) { - if (item.type === 'aux') { - state.channels[0].channel.forEach((channel: any, index: number) => { - channel.auxLevel.forEach((auxLevel: any, auxIndex: number) => { - if (channel.assignedFader >= 0){ - setTimeout(() => { - this.sendOutRequestAux(item.mixerMessage, auxIndex +1, state.faders[0].fader[channel.assignedFader].monitor) - }, - state.faders[0].fader[channel.assignedFader].monitor * 10 + auxIndex * 100) - } - }) - }) - } else { - state.channels[0].channel.map((channel: any, index: any) => { - this.sendOutRequest(item.mixerMessage,(index +1)); - }); - } - - } else { - this.sendOutMessage(item.mixerMessage, 1, item.value, item.type); - } - }, - itemIndex * 100) - }); - } - - pingMixerCommand() { - //Ping OSC mixer if mixerProtocol needs it. - this.mixerProtocol.pingCommand.map((command) => { - this.sendOutMessage( - command.mixerMessage, - 0, - command.value, - command.type - ); - }); - global.mainThreadHandler.updateFullClientStore() - this.mixerOnlineTimer = setTimeout(() => { - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: false - }); - }, this.mixerProtocol.pingTime) - } - - checkOscCommand(message: string, command: string): boolean { - if (message === command) return true; - let messageArray: string[] = message.split('/') - let commandArray: string[] = command.split('/') - let status: boolean = true - if (messageArray.length !== commandArray.length) { - return false - } - commandArray.forEach((commandPart: string, index: number) => { - if (commandPart === '{channel}') { - if (typeof(parseFloat(messageArray[index])) !== 'number') { status = false } - } else if (commandPart === '{argument}') { - if (typeof(parseFloat(messageArray[index])) !== 'number') { status = false } - } else if (commandPart !== messageArray[index]) { - status = false - } - }) - return status - } - - sendOutMessage(oscMessage: string, channel: number, value: string | number, type: string) { - let channelString = this.mixerProtocol.leadingZeros ? ("0"+channel).slice(-2) : channel.toString(); - let message = oscMessage.replace( - "{channel}", - channelString - ); - if (message != 'none') { - logger.verbose('Sending OSC command :' + message, {}) - this.oscConnection.send({ - address: message, - args: [ - { - type: type, - value: value - } - ] - }); - } - } - - - sendOutRequest(oscMessage: string, channel: number) { - let channelString = this.mixerProtocol.leadingZeros ? ("0"+channel).slice(-2) : channel.toString(); - let message = oscMessage.replace( - "{channel}", - channelString - ); - if (message != 'none') { - this.oscConnection.send({ - address: message - }); - } - } - - sendOutRequestAux(oscMessage: string, channel: number, auxSend: number) { - let channelString = this.mixerProtocol.leadingZeros ? ("0"+channel).slice(-2) : channel.toString(); - let message = oscMessage.replace( - "{channel}", - channelString - ); - let auxSendNumber = this.mixerProtocol.leadingZeros ? ("0"+String(auxSend)).slice(-2) : String(auxSend); - message = message.replace('{argument}', auxSendNumber) - logger.verbose('Initial Aux Message : ' + message) - if (message != 'none') { - this.oscConnection.send({ - address: message - }); - } - } - - updateOutLevel(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_OUT_GAIN[0].mixerMessage, - channelTypeIndex+1, - state.channels[0].channel[channelIndex].outputLevel, - "f" - ); - } - - updatePflState(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - if (state.faders[0].fader[channelIndex].pflOn === true) { - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].mixerMessage, - channelTypeIndex+1, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].value, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].type - ); - } else { - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].mixerMessage, - channelTypeIndex+1, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].value, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].type - ); - } - } - - updateMuteState(channelIndex: number, muteOn: boolean) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex - if (muteOn === true) { - let mute = this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_MUTE_ON[0] - this.sendOutMessage( - mute.mixerMessage, - channelTypeIndex + 1, - mute.value, - mute.type - ) - } else { - let mute = this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_MUTE_OFF[0] - this.sendOutMessage( - mute.mixerMessage, - channelTypeIndex + 1, - mute.value, - mute.type - ) - } } - - updateNextAux(channelIndex: number, level: number) { - return true - } - - updateThreshold(channelIndex: number, level: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let thr = this.mixerProtocol.channelTypes[channelType].toMixer.THRESHOLD[0] - level = level * (thr.max-thr.min) + thr.min - this.sendOutMessage( - thr.mixerMessage, - channelTypeIndex+1, - level, - "f" - ); - } - updateRatio(channelIndex: number, level: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let ratio = this.mixerProtocol.channelTypes[channelType].toMixer.RATIO[0] - level = level * (ratio.max-ratio.min) + ratio.min - this.sendOutMessage( - ratio.mixerMessage, - channelTypeIndex+1, - level, - "f" - ); - } - updateDelayTime(channelIndex: number, level: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let delayTime = this.mixerProtocol.channelTypes[channelType].toMixer.DELAY_TIME[0] - level = level * (delayTime.max-delayTime.min) + delayTime.min - this.sendOutMessage( - delayTime.mixerMessage, - channelTypeIndex+1, - level, - "f" - ) - } - updateLow(channelIndex: number, level: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let low = this.mixerProtocol.channelTypes[channelType].toMixer.LOW[0] - level = level * (low.max-low.min) + low.min - this.sendOutMessage( - low.mixerMessage, - channelTypeIndex+1, - level, - "f" - ); - } - updateLoMid(channelIndex: number, level: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let loMid = this.mixerProtocol.channelTypes[channelType].toMixer.LO_MID[0] - level = level * (loMid.max-loMid.min) + loMid.min - this.sendOutMessage( - loMid.mixerMessage, - channelTypeIndex+1, - level, - "f" - ); - } - updateMid(channelIndex: number, level: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let mid = this.mixerProtocol.channelTypes[channelType].toMixer.MID[0] - level = level * (mid.max-mid.min) + mid.min - this.sendOutMessage( - mid.mixerMessage, - channelTypeIndex+1, - level, - "f" - ); - } - updateHigh(channelIndex: number, level: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let high = this.mixerProtocol.channelTypes[channelType].toMixer.HIGH[0] - level = level * (high.max-high.min) + high.min - this.sendOutMessage( - high.mixerMessage, - channelTypeIndex+1, - level, - "f" - ); - } - - updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channel = state.channels[0].channel[channelIndex].channelTypeIndex+1 - let auxSendCmd = this.mixerProtocol.channelTypes[channelType].toMixer.AUX_LEVEL[0] - let auxSendNumber = this.mixerProtocol.leadingZeros ? ("0"+String(auxSendIndex + 1)).slice(-2) : String(auxSendIndex + 1); - let message = auxSendCmd.mixerMessage.replace('{argument}', auxSendNumber) - - level = level * (auxSendCmd.max-auxSendCmd.min) + auxSendCmd.min - this.sendOutMessage( - message, - channel, - level, - "f" - ); - } - - - updateFadeIOLevel(channelIndex: number, outputLevel: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_OUT_GAIN[0].mixerMessage, - channelTypeIndex+1, - String(outputLevel), - "f" - ); - } - - updateChannelName(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let channelName = state.faders[0].fader[channelIndex].label; - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_NAME[0].mixerMessage, - channelTypeIndex+1, - channelName, - "s" - ); - } - - injectCommand(command: string[]) { - return true - } - -} - diff --git a/server/utils/mixerConnections/SSLMixerConnection.ts b/server/utils/mixerConnections/SSLMixerConnection.ts deleted file mode 100644 index 0cfee381..00000000 --- a/server/utils/mixerConnections/SSLMixerConnection.ts +++ /dev/null @@ -1,423 +0,0 @@ -//Node Modules: -const net = require('net') -import { store, state } from '../../reducers/store' -import { huiRemoteConnection } from '../../mainClasses' - -//Utils: -import { IMixerProtocol } from '../../constants/MixerProtocolInterface' -import { IStore } from '../../reducers/indexReducer' -import { SET_OUTPUT_LEVEL } from '../../reducers/channelActions' -import { - SET_FADER_LEVEL, - TOGGLE_PGM, - SET_MUTE - } from '../../reducers/faderActions' -import { SET_MIXER_ONLINE } from '../../reducers/settingsActions'; -import { logger } from '../logger' - -export class SSLMixerConnection { - mixerProtocol: IMixerProtocol; - cmdChannelIndex: number; - SSLConnection: any; - mixerOnlineTimer: any; - - constructor(mixerProtocol: IMixerProtocol) { - this.sendOutLevelMessage = this.sendOutLevelMessage.bind(this); - - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: false - }); - - this.mixerProtocol = mixerProtocol; - - this.cmdChannelIndex = this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage.split('/').findIndex(ch => ch === '{channel}'); - - this.SSLConnection = new net.Socket() - this.SSLConnection.connect(state.settings[0].devicePort, state.settings[0].deviceIp, () => { - logger.info('Connected to SSL', {}) - - } - ); - this.setupMixerConnection(); - } - - formatHexWithSpaces(str: string, item: string, every: number) { - for(let i = 0; i < str.length; i++){ - if(!(i % (every + 1))){ - str = str.substring(0, i) + item + str.substring(i); - } - } - return str.substring(1); - } - - setupMixerConnection() { - // Return command was an acknowledge: - let lastWasAck = false - - this.SSLConnection - .on("ready", () => { - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: true - }); - - logger.info("Receiving state of desk", {}) - this.mixerProtocol.initializeCommands.map((item) => { - if (item.mixerMessage.includes("{channel}")) { - state.channels[0].channel.map((channel: any, index: any) => { - this.sendOutRequest(item.mixerMessage, index); - }); - } else { - this.sendOutLevelMessage(item.mixerMessage, 0, item.value); - } - }); - global.mainThreadHandler.updateFullClientStore() - }) - .on('data', (data: any) => { - clearTimeout(this.mixerOnlineTimer) - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: true - }); - - let buffers = [] - let lastIndex = 0 - for (let index=1; index { - if (buffer[1] === 6 && buffer[2] === 255 && !lastWasAck) { - lastWasAck = false - // FADERLEVEL COMMAND: - try { - - - let commandHex = buffer.toString('hex') - let channel = buffer[6] - let value = buffer.readUInt16BE(7)/1024 - - let assignedFaderIndex = state.channels[0].channel[channel].assignedFader - if (!state.channels[0].channel[channel].fadeActive) { - if (value > this.mixerProtocol.fader.min + (this.mixerProtocol.fader.max * state.settings[0].autoResetLevel / 100)) { - store.dispatch({ - type: SET_FADER_LEVEL, - channel: assignedFaderIndex, - level: value - }); - if (!state.faders[0].fader[assignedFaderIndex].pgmOn) { - store.dispatch({ - type: TOGGLE_PGM, - channel: assignedFaderIndex - }); - } - - if (huiRemoteConnection) { - huiRemoteConnection.updateRemoteFaderState(assignedFaderIndex, value); - } - if (state.faders[0].fader[assignedFaderIndex].pgmOn) { - state.channels[0].channel.map((channel: any, index: number) => { - if (channel.assignedFader === assignedFaderIndex) { - this.updateOutLevel(index); - } - }) - } - } else if (state.faders[0].fader[assignedFaderIndex].pgmOn - || state.faders[0].fader[assignedFaderIndex].voOn) - { - store.dispatch({ - type: SET_FADER_LEVEL, - channel: assignedFaderIndex, - level: value - }); - state.channels[0].channel.forEach((item, index) => { - if (item.assignedFader === assignedFaderIndex) { - store.dispatch({ - type: SET_OUTPUT_LEVEL, - channel: index, - level: value - }); - } - }) - } - global.mainThreadHandler.updatePartialStore(assignedFaderIndex) - } - } catch (error) { - logger.error('Error translating received message :' + String(error), {}) - } - - } else if (buffer[1] === 5 && buffer[2] === 255 && buffer[4] === 1 && !lastWasAck) { - lastWasAck = false - // MUTE ON/OFF COMMAND - let commandHex = buffer.toString('hex') - let channelIndex = buffer[6] - let value: boolean = buffer[7] === 0 ? true : false - logger.verbose('Receive Buffer Channel On/off: ' + this.formatHexWithSpaces(commandHex, ' ', 2), {}) - - let assignedFaderIndex = state.channels[0].channel[channelIndex].assignedFader - - store.dispatch({ - type: SET_MUTE, - channel: assignedFaderIndex, - muteOn: value - }); - - if (huiRemoteConnection) { - huiRemoteConnection.updateRemoteFaderState(assignedFaderIndex, value ? 1 : 0); - } - state.channels[0].channel.forEach((channel: any, index: number) => { - if (channel.assignedFader === assignedFaderIndex && index !== channelIndex) { - this.updateMuteState(index, state.faders[0].fader[assignedFaderIndex].muteOn); - } - }) - global.mainThreadHandler.updatePartialStore(assignedFaderIndex) - } else { - let commandHex = buffer.toString('hex') - logger.verbose('Receieve Buffer Hex: ' + this.formatHexWithSpaces(commandHex, ' ', 2), {}) - } - if (buffer[0] === 4) { - lastWasAck = true - } else { - lastWasAck = false - } - }) - }) - .on('error', (error: any) => { - logger.error("Error : " + String(error), {}) - logger.info("Lost SCP connection", {}) - }); - - //Ping mixer to get mixerOnlineState - let oscTimer = setInterval( - () => { - this.pingMixerCommand(); - }, - this.mixerProtocol.pingTime - ); - } - - pingMixerCommand() { - //Ping OSC mixer if mixerProtocol needs it. - this.mixerProtocol.pingCommand.forEach((command) => { - this.sendOutPingRequest(); - }); - global.mainThreadHandler.updateFullClientStore() - this.mixerOnlineTimer = setTimeout(() => { - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: false - }); - }, this.mixerProtocol.pingTime) - } - - checkSSLCommand(message: string, command: string) { - if (!message) return false - if (message.slice(0, command.length) === command) return true; - return false; - } - - calculate_checksum8(hexValues: string) { - // convert input value to upper case - hexValues = hexValues.toUpperCase(); - - let strHex = new String("0123456789ABCDEF"); - let result = 0; - let fctr = 16; - - for (let i = 0; i < hexValues.length; i++) { - if (hexValues.charAt(i) == " ") - continue; - - let v = strHex.indexOf(hexValues.charAt(i)); - if (v < 0) { - result = -1; - break; - } - result += v * fctr; - - if (fctr == 16) - fctr = 1; - else - fctr = 16; - } - - // Calculate 2's complement - result = (~(result & 0xff) + 1) & 0xFF; - // Convert result to string - return strHex.charAt(Math.floor(result / 16)) + strHex.charAt(result % 16); - } - - - sendOutLevelMessage(sslMessage: string, channelIndex: number, value: string | number) { - let valueNumber: number - if (typeof value === 'string') { - value = parseFloat(value) - } - if (value < 0) { - value = 0 - } - valueNumber = value * 1024 - let valueByte = new Uint8Array([ - (valueNumber & 0x0000ff00) >> 8, - (valueNumber & 0x000000ff), - ]) - - let channelByte = new Uint8Array([ - (channelIndex & 0x0000ff00) >> 8, - (channelIndex & 0x000000ff), - ]) - - sslMessage = sslMessage.replace('{channel}', ('0' + channelByte[0].toString(16)).slice(-2) + ' ' + ('0' + channelByte[1].toString(16)).slice(-2)) - sslMessage = sslMessage.replace('{level}', ('0' + valueByte[0].toString(16)).slice(-2) + ' ' + ('0' + valueByte[1].toString(16)).slice(-2) + ' ') - sslMessage = sslMessage + this.calculate_checksum8(sslMessage.slice(9)) - let a = sslMessage.split(' ') - let buf = new Buffer(a.map((val:string) => { return parseInt(val, 16) })) - - logger.verbose("Send HEX: " + sslMessage, {}) - this.SSLConnection.write(buf) - } - - sendOutRequest(sslMessage: string, channelIndex: number) { - //let sslMessage = 'f1 06 00 80 00 00 {channel} {level}' - let channelByte = new Uint8Array([ - (channelIndex & 0x0000ff00) >> 8, - (channelIndex & 0x000000ff), - ]) - sslMessage = sslMessage.replace('{channel}', ('0' + channelByte[0].toString(16)).slice(-2) + ' ' + ('0' + channelByte[1].toString(16)).slice(-2)) - sslMessage = sslMessage + ' ' + this.calculate_checksum8(sslMessage.slice(9)) - let a = sslMessage.split(' ') - let buf = new Buffer(a.map((val:string) => { return parseInt(val, 16) })) - - logger.verbose("Send HEX: " + sslMessage, {}) - this.SSLConnection.write(buf) - } - - sendOutPingRequest() { - let sslMessage = 'f1 02 00 07 00' - sslMessage = sslMessage + ' ' + this.calculate_checksum8(sslMessage.slice(9)) - let a = sslMessage.split(' ') - let buf = new Buffer(a.map((val:string) => { return parseInt(val, 16) })) - - logger.verbose("Send HEX: " + sslMessage, {}) - this.SSLConnection.write(buf) - } - - updateOutLevel(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let faderIndex = state.channels[0].channel[channelIndex].assignedFader; - if (state.faders[0].fader[faderIndex].pgmOn) { - store.dispatch({ - type:SET_OUTPUT_LEVEL, - channel: channelIndex, - level: state.faders[0].fader[faderIndex].faderLevel - }); - } - this.sendOutLevelMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_OUT_GAIN[0].mixerMessage, - channelTypeIndex, - state.channels[0].channel[channelIndex].outputLevel - ); - } - - updatePflState(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - if (state.faders[0].fader[channelIndex].pflOn === true) { - this.sendOutRequest( - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].mixerMessage, - channelTypeIndex - ); - } else { - this.sendOutRequest( - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].mixerMessage, - channelTypeIndex - ); - } - } - - updateMuteState(channelIndex: number, muteOn: boolean) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - if (muteOn === true) { - this.sendOutRequest( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_MUTE_ON[0].mixerMessage, - channelTypeIndex - ); - } else { - this.sendOutRequest( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_MUTE_OFF[0].mixerMessage, - channelTypeIndex - ); - } - } - - updateFadeIOLevel(channelIndex: number, outputLevel: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - this.sendOutLevelMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_OUT_GAIN[0].mixerMessage, - channelTypeIndex, - String(outputLevel) - ); - } - - updateNextAux(channelIndex: number, level: number) { - this.sendOutLevelMessage( - this.mixerProtocol.channelTypes[0].toMixer.NEXT_SEND[0].mixerMessage, - channelIndex + 128, - level - ); - } - updateThreshold(channelIndex: number, level: number) { - return true - } - updateRatio(channelIndex: number, level: number) { - return true - - } - updateDelayTime(channelIndex: number, level: number) { - return true - } - updateLow(channelIndex: number, level: number) { - return true - } - updateLoMid(channelIndex: number, level: number) { - return true - } - updateMid(channelIndex: number, level: number) { - return true - } - updateHigh(channelIndex: number, level: number) { - return true - } - updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { - return true - } - - updateChannelName(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let channelName = state.faders[0].fader[channelIndex].label; - /* - this.sendOutLevelMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_NAME[0].mixerMessage, - channelTypeIndex, - channelName - ); - */ - } - - injectCommand(command: string[]) { - return true - } - -} - diff --git a/server/utils/mixerConnections/YamahaQlClConnection.ts b/server/utils/mixerConnections/YamahaQlClConnection.ts deleted file mode 100644 index 43fd71f7..00000000 --- a/server/utils/mixerConnections/YamahaQlClConnection.ts +++ /dev/null @@ -1,344 +0,0 @@ -//Node Modules: -const net = require('net') -import { store, state } from '../../reducers/store' -import { huiRemoteConnection } from '../../mainClasses' - - -//Utils: -import { IMixerProtocol } from '../../constants/MixerProtocolInterface' -import { SET_OUTPUT_LEVEL } from '../../reducers/channelActions' -import { - SET_VU_LEVEL, - SET_FADER_LEVEL, - SET_CHANNEL_LABEL, - TOGGLE_PGM, - SET_MUTE -} from '../../reducers/faderActions' -import { logger } from '../logger' -import { SET_MIXER_ONLINE } from '../../reducers/settingsActions' - - - -export class QlClMixerConnection { - mixerProtocol: IMixerProtocol - cmdChannelIndex: number - midiConnection: any - mixerOnlineTimer: any - - - constructor(mixerProtocol: IMixerProtocol) { - this.sendOutMessage = this.sendOutMessage.bind(this); - this.pingMixerCommand = this.pingMixerCommand.bind(this); - - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: false - }); - - this.mixerProtocol = mixerProtocol; - - this.cmdChannelIndex = this.mixerProtocol.channelTypes[0].fromMixer.CHANNEL_OUT_GAIN[0].mixerMessage.split('/').findIndex(ch => ch === '{channel}'); - - this.midiConnection = new net.Socket() - this.midiConnection.connect(50000, state.settings[0].deviceIp, () => { - logger.info('Connected to Yamaha mixer', {}) - - } - ); - this.setupMixerConnection(); - } - - setupMixerConnection() { - this.midiConnection - .on("ready", () => { - logger.info("Receiving state of desk", {}) - this.mixerProtocol.initializeCommands.map((item) => { - if (item.mixerMessage.includes("{channel}")) { - state.channels[0].channel.map((channel: any, index: any) => { - this.sendOutMessage(item.mixerMessage, (index + 1), 0, '') - }) - } else { - this.sendOutMessage(item.mixerMessage, 0, item.value, item.type) - } - }) - global.mainThreadHandler.updateFullClientStore() - }) - .on('data', (data: any) => { - clearTimeout(this.mixerOnlineTimer) - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: true - }); - - let buffers = [] - let lastIndex = 0 - for (let index=1; index { - logger.verbose("Received Midi Message : " + message.toString('hex')) - if (this.checkMidiCommand(message, this.mixerProtocol.channelTypes[0].fromMixer - .CHANNEL_VU[0].mixerMessage)) { - let mixerValues: string[] = message.split(' ') - let ch = parseInt(mixerValues[3]) - let assignedFader = 1 + state.channels[0].channel[ch - 1].assignedFader - let mixerValue = parseInt(mixerValues[6]) - store.dispatch({ - type: SET_VU_LEVEL, - channel: assignedFader, - level: mixerValue - } - ) - } else if (this.checkMidiCommand(message, this.mixerProtocol.channelTypes[0].fromMixer - .CHANNEL_OUT_GAIN[0].mixerMessage)) { - let ch = 1 + (message[11] | message[10] << 8) - let assignedFader = 1 + state.channels[0].channel[ch - 1].assignedFader - let mixerLevel: number = message[16] | message[15] << 8 // parseFloat(message[16]) - let faderLevel = Math.pow(2, (mixerLevel) / 1920) - 1 - //let faderLevel = Math.log10((mixerLevel + 32768) / (1000 + 32768)) - if (!state.channels[0].channel[ch - 1].fadeActive - && faderLevel > this.mixerProtocol.fader.min) { - store.dispatch({ - type: SET_FADER_LEVEL, - channel: assignedFader - 1, - level: faderLevel - }); - if (!state.faders[0].fader[assignedFader - 1].pgmOn) { - store.dispatch({ - type: TOGGLE_PGM, - channel: assignedFader - 1 - }); - } - - if (huiRemoteConnection) { - huiRemoteConnection.updateRemoteFaderState(assignedFader - 1, faderLevel); - } - if (state.faders[0].fader[assignedFader - 1].pgmOn) { - state.channels[0].channel.map((channel: any, index: number) => { - if (channel.assignedFader === assignedFader - 1) { - this.updateOutLevel(index); - } - }) - } - - } - global.mainThreadHandler.updatePartialStore(assignedFader - 1) - - } else if (this.checkMidiCommand(message, this.mixerProtocol.channelTypes[0].fromMixer - .CHANNEL_MUTE_ON[0].mixerMessage)) { - // MUTE ON/OFF COMMAND - let channelIndex = (message[11] | message[10] << 8) - - let value: boolean = message[16] === 0 ? true : false - logger.verbose('Receive Buffer Channel On/off - Channel ' + String(channelIndex + 1) + ' Val :' + String(message[16]) ) - - let assignedFaderIndex = state.channels[0].channel[channelIndex].assignedFader - - store.dispatch({ - type: SET_MUTE, - channel: assignedFaderIndex, - muteOn: value - }); - - if (huiRemoteConnection) { - huiRemoteConnection.updateRemoteFaderState(assignedFaderIndex, value ? 1 : 0); - } - state.channels[0].channel.forEach((channel: any, index: number) => { - if (channel.assignedFader === assignedFaderIndex && index !== channelIndex) { - this.updateMuteState(index, state.faders[0].fader[assignedFaderIndex].muteOn); - } - }) - global.mainThreadHandler.updatePartialStore(assignedFaderIndex) - } - }) - }) - .on('error', (error: any) => { - logger.error("Error : " + String(error), {}) - logger.info("Lost QlCl connection", {}) - }); - - //Ping OSC mixer if mixerProtocol needs it. - if (this.mixerProtocol.pingTime > 0) { - let oscTimer = setInterval( - () => { - this.pingMixerCommand(); - }, - this.mixerProtocol.pingTime - ); - } - } - - pingMixerCommand() { - this.mixerOnlineTimer = setTimeout(() => { - store.dispatch({ - type: SET_MIXER_ONLINE, - mixerOnline: false - }); - }, this.mixerProtocol.pingTime) - } - - checkMidiCommand(midiMessage: number[], command: string) { - if (!midiMessage) return false - let commandArray = command.split(' ') - let valid = true - for (let i=0; i <= 8; i++) { - if (i < midiMessage.length) { - if (("0" + midiMessage[i].toString(16)).substr(-2) !== commandArray[i]) { - valid = false - } - } else { - valid = false - } - } - return valid - } - - sendOutMessage(message: string, channel: number, value: string | number, type: string) { - let valueNumber: number - if (typeof value === 'string') { - value = parseFloat(value) - } - - valueNumber = value * 2048 - let valueByte = new Uint8Array([ - (valueNumber & 0xff00) >> 8, - (valueNumber & 0x00ff), - ]) - - let channelByte = new Uint8Array([ - (channel & 0xff00) >> 8, - (channel & 0x00ff), - ]) - - let command = message.replace('{channel}', channelByte[0].toString(16) + ' ' + channelByte[1].toString(16)) - command = command.replace('{level}', valueByte[0].toString(16) + ' ' + valueByte[1].toString(16)) - let a = command.split(' ') - let buf = new Buffer(a.map((val:string) => { return parseInt(val, 16) })) - logger.verbose("Sending Command :" + command) - this.midiConnection.write(buf) - } - - updateOutLevel(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let faderIndex = state.channels[0].channel[channelIndex].assignedFader; - if (state.faders[0].fader[faderIndex].pgmOn) { - store.dispatch({ - type:SET_OUTPUT_LEVEL, - channel: channelIndex, - level: state.faders[0].fader[faderIndex].faderLevel - }); - } - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_OUT_GAIN[0].mixerMessage, - channelTypeIndex, - state.channels[0].channel[channelIndex].outputLevel, - "f" - ); - } - - updatePflState(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - if (state.faders[0].fader[channelIndex].pflOn === true) { - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].mixerMessage, - channelTypeIndex, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].value, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_ON[0].type - ); - } else { - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].mixerMessage, - channelTypeIndex, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].value, - this.mixerProtocol.channelTypes[channelType].toMixer.PFL_OFF[0].type - ); - } - } - - updateMuteState(channelIndex: number, muteOn: boolean) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - if (muteOn === true) { - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_MUTE_ON[0].mixerMessage, - channelTypeIndex, - '', - '' - ); - } else { - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_MUTE_OFF[0].mixerMessage, - channelTypeIndex, - '', - '' - ); - } - } - - updateNextAux(channelIndex: number, level: number) { - return true - } - updateThreshold(channelIndex: number, level: number) { - return true - } - updateRatio(channelIndex: number, level: number) { - return true - - } - updateDelayTime(channelIndex: number, level: number) { - return true - } - updateLow(channelIndex: number, level: number) { - return true - } - updateLoMid(channelIndex: number, level: number) { - return true - } - updateMid(channelIndex: number, level: number) { - return true - } - updateHigh(channelIndex: number, level: number) { - return true - } - updateAuxLevel(channelIndex: number, auxSendIndex: number, level: number) { - return true - } - - updateFadeIOLevel(channelIndex: number, outputLevel: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_OUT_GAIN[0].mixerMessage, - channelTypeIndex, - String(outputLevel), - "f" - ); - } - - updateChannelName(channelIndex: number) { - let channelType = state.channels[0].channel[channelIndex].channelType; - let channelTypeIndex = state.channels[0].channel[channelIndex].channelTypeIndex; - let channelName = state.faders[0].fader[channelIndex].label; - this.sendOutMessage( - this.mixerProtocol.channelTypes[channelType].toMixer.CHANNEL_NAME[0].mixerMessage, - channelTypeIndex, - channelName, - "s" - ); - } - - injectCommand(command: string[]) { - return true - } - -} - diff --git a/server/utils/mixerConnections/productSpecific/behringer.ts b/server/utils/mixerConnections/productSpecific/behringer.ts deleted file mode 100644 index 048c48a2..00000000 --- a/server/utils/mixerConnections/productSpecific/behringer.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { store, state } from '../../../reducers/store' -import { socketServer } from '../../../expressHandler' - -import * as DEFAULTS from '../../../constants/DEFAULTS'; -import { SET_VU_LEVEL } from '../../../reducers/faderActions' -import { SOCKET_SET_VU } from '../../../constants/SOCKET_IO_DISPATCHERS'; - - -export const behringerMeter = (message: any) => { - - //Test data from Behringer: - //message = [40, 0, 0, 0, 133, 157, 183, 156, 72, 154, 101, 157, 229, 162, 241, 158, 253, 162, 156, 162, 131, 162, 253, 162, 81, 162, 29, 162, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 0, 128, 223, 157, 223, 157, 223, 157, 223, 157]; - - let uint8bytes = Uint8Array.from(message[0]); - let dataview = new DataView(uint8bytes.buffer); - - for (let i=0; i < state.settings[0].numberOfChannelsInType[0]; i++) { - let level = (dataview.getInt16(2*(i+2) , true) + 8000)/8000 - store.dispatch({ - type:SET_VU_LEVEL, - channel: i, - level: level - }); - socketServer.emit( - SOCKET_SET_VU, - { - faderIndex: state.channels[0].channel[i].assignedFader, - level: level - } - ) - } -}; - diff --git a/server/utils/mixerConnections/productSpecific/midas.ts b/server/utils/mixerConnections/productSpecific/midas.ts deleted file mode 100644 index 807a663d..00000000 --- a/server/utils/mixerConnections/productSpecific/midas.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { store, state } from '../../../reducers/store' -import { socketServer } from '../../../expressHandler' - -import { SET_ALL_VU_LEVELS } from '../../../reducers/faderActions' -import { SOCKET_SET_VU } from '../../../constants/SOCKET_IO_DISPATCHERS'; - -export const midasMeter = (message: any) => { - - const headerData = 4; - let uint8bytes = Uint8Array.from(message[0]); - let dataview = new DataView(uint8bytes.buffer); - let vuMeters = []; - let numberOfChannels = state.settings[0].numberOfChannelsInType[0]; - - for (let i=0; i < numberOfChannels; i++) { - let level = dataview.getFloat32(4*i+headerData , true) - vuMeters.push({vuVal : level}); - socketServer.emit( - SOCKET_SET_VU, - { - faderIndex: state.channels[0].channel[i].assignedFader, - level: level - } - ) - } - store.dispatch({ - type: SET_ALL_VU_LEVELS, - vuMeters: vuMeters - }); - - -}; - diff --git a/shared/package.json b/shared/package.json new file mode 100644 index 00000000..a1c7effb --- /dev/null +++ b/shared/package.json @@ -0,0 +1,12 @@ +{ + "name": "shared", + "version": "0.0.0", + "license": "MIT", + "devDependencies": { + "@types/node": "^18.16.0", + "typescript": "^5.0.4" + }, + "dependencies": { + "redux": "^4.2.1" + } +} diff --git a/shared/src/actions/channelActions.ts b/shared/src/actions/channelActions.ts new file mode 100644 index 00000000..aaaa72d5 --- /dev/null +++ b/shared/src/actions/channelActions.ts @@ -0,0 +1,115 @@ +import { IChannel, IChannels, InumberOfChannels } from '../reducers/channelsReducer' + +export const SET_OUTPUT_LEVEL = 'SET_OUTPUT_LEVEL' +export const SET_AUX_LEVEL = 'SET_AUX_LEVEL' +export const SET_COMPLETE_CH_STATE = 'SET_COMPLETE_CH_STATE' +export const SET_SINGLE_CH_STATE = 'SET_SINGLE_CH_STATE' +export const FADE_ACTIVE = 'FADE_ACTIVE' +export const SET_ASSIGNED_FADER = 'SET_ASSIGNED_FADER' +export const SET_PRIVATE = 'SET_PRIVATE' +export const SET_CHANNEL_LABEL = 'SET_CHANNEL_LABEL' +export const FLUSH_CHANNEL_LABELS = 'FLUSH_CHANNEL_LABELS' + +export const storeSetOutputLevel = ( + mixerIndex: number, + channel: number, + level: number +) => { + return { + type: SET_OUTPUT_LEVEL, + mixerIndex: mixerIndex, + channel: channel, + level: level, + } +} + +export const storeSetAuxLevel = ( + mixerIndex: number, + channel: number, + auxIndex: number, + level: number +) => { + return { + type: SET_AUX_LEVEL, + mixerIndex: mixerIndex, + channel: channel, + auxIndex: auxIndex, + level: level, + } +} + +export const storeSetCompleteChState = ( + allState: IChannels, + numberOfChannels: InumberOfChannels[] +) => { + return { + type: SET_COMPLETE_CH_STATE, + allState: allState, + numberOfTypeChannels: numberOfChannels, + } +} + +export const storeSetSingleChState = ( + channelIndex: number, + state: IChannel +) => { + return { + type: SET_SINGLE_CH_STATE, + channelIndex: channelIndex, + state: state, + } +} + +export const storeFadeActive = ( + mixerIndex: number, + channelIndex: number, + active: boolean +) => { + return { + type: FADE_ACTIVE, + mixerIndex: mixerIndex, + channel: channelIndex, + active: active, + } +} + +export const storeSetAssignedFader = ( + mixerIndex: number, + channel: number, + faderNumber: number +) => { + return { + type: SET_ASSIGNED_FADER, + mixerIndex: mixerIndex, + channel: channel, + faderNumber: faderNumber, + } +} + +export const storeSetChPrivate = (channel: number, tag: string, value: any) => { + return { + type: SET_PRIVATE, + channel: channel, + tag: tag, + value: value, + } +} + +export const storeSetChLabel = ( + mixerIndex: number, + channel: number, + label: string +) => { + return { + type: SET_CHANNEL_LABEL, + mixerIndex: mixerIndex, + channel: channel, + label: label, + } +} + +export const storeFlushChLabels = () => { + return { + type: FLUSH_CHANNEL_LABELS, + } +} diff --git a/shared/src/actions/faderActions.ts b/shared/src/actions/faderActions.ts new file mode 100644 index 00000000..b3ac8e04 --- /dev/null +++ b/shared/src/actions/faderActions.ts @@ -0,0 +1,347 @@ +import { fxParamsList } from '../constants/MixerProtocolInterface' +import { IFader, IFaders } from '../reducers/fadersReducer' + +export const SET_VU_REDUCTION_LEVEL = 'SET_REDUCTION_LEVEL' +export const SET_COMPLETE_FADER_STATE = 'SET_COMPLETE_FADER_STATE' +export const SET_SINGLE_FADER_STATE = 'SET_SINGLE_FADER_STATE' +export const SET_FADER_LEVEL = 'SET_FADER_LEVEL' +export const SET_INPUT_GAIN = 'SET_INPUT_GAIN' +export const SET_INPUT_SELECTOR = 'SET_INPUT_SELECTOR' +export const SET_FADER_LABEL = 'SET_FADER_LABEL' +export const SET_USER_LABEL = 'SET_USER_LABEL' +export const SET_FADER_FX = 'SET_FADER_FX' +export const SET_FADER_MONITOR = 'SET_FADER_MONITOR' +export const SET_ASSIGNED_CHANNEL = 'SET_ASSIGNED_CHANNEL' +export const REMOVE_ALL_ASSIGNED_CHANNELS = 'REMOVE_ASSIGNED_CHANNELS' +export const TOGGLE_PGM = 'TOGGLE_PGM' +export const SET_PGM = 'SET_PGM' +export const TOGGLE_VO = 'TOGGLE_VO' +export const SET_VO = 'SET_VO' +export const TOGGLE_SLOW_FADE = 'TOGGLE_SLOW_FADE' +export const TOGGLE_PST = 'TOGGLE_PST' +export const SET_PST = 'SET_PST' +export const SET_PST_VO = 'SET_PST_VO' +export const TOGGLE_PFL = 'TOGGLE_PFL' +export const SET_PFL = 'SET_PFL' +export const TOGGLE_MUTE = 'TOGGLE_MUTE' +export const SET_MUTE = 'SET_MUTE' +export const SHOW_CHANNEL = 'SHOW_CHANNEL' +export const SHOW_IN_MINI_MONITOR = 'SHOW_IN_MINI_MONITOR' +export const IGNORE_AUTOMATION = 'IGNORE_AUTOMATION' +export const X_MIX = 'X_MIX' +export const NEXT_MIX = 'NEXT_MIX' +export const FADE_TO_BLACK = 'FADE_TO_BLACK' + +export const UPDATE_LABEL_LIST = 'UPDATE_LABEL_LIST' +export const FLUSH_FADER_LABELS = 'FLUSH_FADER_LABELS' +export const CLEAR_PST = 'CLEAR_PST' +export const SNAP_RECALL = 'SNAP_RECALL' +export const SET_CHANNEL_DISABLED = 'SET_CHANNEL_DISABLED' +export const TOGGLE_AMIX = 'TOGGLE_AMIX' +export const SET_AMIX = 'SET_AMIX' +export const SET_CAPABILITY = 'SET_CAPABILITY' +export const TOGGLE_ALL_MANUAL = 'TOGGLE_ALL_MANUAL' + +export const storeVuReductionLevel = (faderIndex: number, level: number) => { + return { + type: SET_VU_REDUCTION_LEVEL, + faderIndex: faderIndex, + level: level, + } +} + +export const storeSetCompleteFaderState = ( + allState: IFaders, + numberOfTypeChannels: number +) => { + return { + type: SET_COMPLETE_FADER_STATE, + numberOfTypeChannels: numberOfTypeChannels, + allState: allState, + } +} + +export const storeSetSingleFaderState = (faderIndex: number, state: IFader) => { + return { + type: SET_SINGLE_FADER_STATE, + faderIndex: faderIndex, + state: state, + } +} + +export const storeFaderLevel = (faderIndex: number, level: number) => { + return { + type: SET_FADER_LEVEL, + faderIndex: faderIndex, + level: level, + } +} + +export const storeInputGain = (faderIndex: number, level: number) => { + return { + type: SET_INPUT_GAIN, + faderIndex: faderIndex, + level: level, + } +} + +export const storeInputSelector = (faderIndex: number, selected: number) => { + return { + type: SET_INPUT_SELECTOR, + faderIndex: faderIndex, + selected: selected, + } +} + +export const storeFaderLabel = (faderIndex: number, label: string) => { + return { + type: SET_FADER_LABEL, + faderIndex: faderIndex, + label: label, + } +} + +export const storeUserLabel = (faderIndex: number, label: string) => { + return { + type: SET_USER_LABEL, + faderIndex: faderIndex, + label: label, + } +} + +export const storeFaderFx = ( + fxParam: fxParamsList, + faderIndex: number, + level: number +) => { + return { + type: SET_FADER_FX, + fxParam: fxParam, + faderIndex: faderIndex, + level: level, + } +} + +export const storeFaderMonitor = (faderIndex: number, auxIndex: number) => { + return { + type: SET_FADER_MONITOR, + faderIndex: faderIndex, + auxIndex: auxIndex, + } +} + +export const storeTogglePgm = (faderIndex: number) => { + return { + type: TOGGLE_PGM, + faderIndex: faderIndex, + } +} + +export const storeSetPgm = (faderIndex: number, pgmOn: boolean) => { + return { + type: SET_PGM, + faderIndex: faderIndex, + pgmOn: pgmOn, + } +} + +export const storeToggleVo = (faderIndex: number) => { + return { + type: TOGGLE_VO, + faderIndex: faderIndex, + } +} + +export const storeSetVo = (faderIndex: number, voOn: boolean) => { + return { + type: SET_VO, + faderIndex: faderIndex, + voOn: voOn, + } +} + +export const storeToggleSlowFade = (faderIndex: number) => { + return { + type: TOGGLE_SLOW_FADE, + faderIndex: faderIndex, + } +} + +export const storeTogglePst = (faderIndex: number) => { + return { + type: TOGGLE_PST, + faderIndex: faderIndex, + } +} + +export const storeSetPst = (faderIndex: number, pstOn: boolean) => { + return { + type: SET_PST, + faderIndex: faderIndex, + pstOn: pstOn, + } +} + +export const storeSetPstVo = (faderIndex: number, pstVoOn: boolean) => { + return { + type: SET_PST_VO, + faderIndex: faderIndex, + pstVoOn: pstVoOn, + } +} + +export const storeTogglePfl = (faderIndex: number) => { + return { + type: TOGGLE_PFL, + faderIndex: faderIndex, + } +} + +export const storeSetPfl = (faderIndex: number, pflOn: boolean) => { + return { + type: SET_PFL, + faderIndex: faderIndex, + pflOn: pflOn, + } +} + +export const storeToggleMute = (faderIndex: number) => { + return { + type: TOGGLE_MUTE, + faderIndex: faderIndex, + } +} + +export const storeSetMute = (faderIndex: number, muteOn: boolean) => { + return { + type: SET_MUTE, + faderIndex: faderIndex, + muteOn: muteOn, + } +} + +export const storeShowChannel = (faderIndex: number, showChannel: boolean) => { + return { + type: SHOW_CHANNEL, + faderIndex: faderIndex, + showChannel: showChannel, + } +} + +export const storeShowInMiniMonitor = ( + faderIndex: number, + showInMiniMonitor: boolean +) => { + return { + type: SHOW_IN_MINI_MONITOR, + faderIndex: faderIndex, + showInMiniMonitor: showInMiniMonitor, + } +} + +export const storeToggleIgnoreAutomation = (faderIndex: number) => { + return { + type: IGNORE_AUTOMATION, + faderIndex: faderIndex, + } +} + +export const storeXmix = () => { + return { + type: X_MIX, + } +} + +export const storeNextMix = () => { + return { + type: NEXT_MIX, + } +} + +export const storeFadeToBlack = () => { + return { + type: FADE_TO_BLACK, + } +} + +export const storeClearPst = () => { + return { + type: CLEAR_PST, + } +} + +export const storeChannelDisabled = (faderIndex: number, disabled: boolean) => { + return { + type: SET_CHANNEL_DISABLED, + faderIndex: faderIndex, + disabled: disabled, + } +} + +export const storeToggleAMix = (faderIndex: number) => { + return { + type: TOGGLE_AMIX, + faderIndex: faderIndex, + } +} + +export const storeSetAMix = (faderIndex: number, state: boolean) => { + return { + type: SET_AMIX, + faderIndex: faderIndex, + state: state, + } +} + +export const removeAllAssignedChannels = () => { + return { + type: REMOVE_ALL_ASSIGNED_CHANNELS, + } +} + +export const storeSetAssignedChannel = ( + faderIndex: number, + mixerIndex: number, + channelIndex: number, + assigned: boolean +) => { + return { + type: SET_ASSIGNED_CHANNEL, + faderIndex: faderIndex, + mixerIndex: mixerIndex, + channelIndex: channelIndex, + assigned: assigned, + } +} + +export const storeCapability = ( + faderIndex: number, + capability: string, + enabled: boolean +) => { + return { + type: SET_CAPABILITY, + faderIndex: faderIndex, + capability: capability, + enabled: enabled, + } +} + +export const storeAllManual = () => { + return { + type: TOGGLE_ALL_MANUAL, + } +} + +export const updateLabels = (update: Record) => { + return { + type: UPDATE_LABEL_LIST, + update, + } +} + +export const flushExtLabels = () => { + return { + type: FLUSH_FADER_LABELS, + } +} diff --git a/shared/src/actions/settingsActions.ts b/shared/src/actions/settingsActions.ts new file mode 100644 index 00000000..1b3a5e95 --- /dev/null +++ b/shared/src/actions/settingsActions.ts @@ -0,0 +1,105 @@ +import { ICustomPages, PageType } from '../reducers/settingsReducer' + +export const TOGGLE_SHOW_SETTINGS = 'TOGGLE_SHOW_SETTINGS' +export const TOGGLE_SHOW_PAGES_SETUP = 'TOGGLE_SHOW_PAGES_SETUP' +export const TOGGLE_SHOW_LABEL_SETTINGS = 'TOGGLE_SHOW_LABEL_SETTINGS' +export const TOGGLE_SHOW_CHAN_STRIP = 'TOGGLE_SHOW_CHAN_STRIP' +export const TOGGLE_SHOW_CHAN_STRIP_FULL = 'TOGGLE_SHOW_CHAN_STRIP_FULL' +export const TOGGLE_SHOW_OPTION = 'TOGGLE_SHOW_OPTION' +export const TOGGLE_SHOW_MONITOR_OPTIONS = 'TOGGLE_SHOW_MONITOR_OPTIONS' +export const TOGGLE_SHOW_STORAGE = 'TOGGLE_SHOW_STORAGE' +export const UPDATE_SETTINGS = 'UPDATE_SETTINGS' +export const SET_MIXER_ONLINE = 'SET_MIXER_ONLINE' +export const SET_SERVER_ONLINE = 'SET_SERVER_ONLINE' +export const SET_PAGE = 'SET_PAGE' +export const SET_PAGES_LIST = 'SET_PAGES_LIST' + +export const storeShowSettings = () => { + return { + type: TOGGLE_SHOW_SETTINGS, + } +} +export const storeShowPagesSetup = () => { + return { + type: TOGGLE_SHOW_PAGES_SETUP, + } +} +export const storeShowLabelSetup = () => { + return { + type: TOGGLE_SHOW_LABEL_SETTINGS, + } +} +export const storeShowChanStrip = (faderIndex: number) => { + return { + type: TOGGLE_SHOW_CHAN_STRIP, + channel: faderIndex, + } +} +export const storeShowChanStripFull = (faderIndex: number) => { + return { + type: TOGGLE_SHOW_CHAN_STRIP_FULL, + channel: faderIndex, + } +} +export const storeShowOptions = (faderIndex: number) => { + return { + type: TOGGLE_SHOW_OPTION, + channel: faderIndex, + } +} +export const storeShowMonitorOptions = (faderIndex: number) => { + return { + type: TOGGLE_SHOW_MONITOR_OPTIONS, + channel: faderIndex, + } +} +export const storeShowStorage = () => { + return { + type: TOGGLE_SHOW_STORAGE, + } +} +export const storeUpdateSettings = (settings: any) => { + return { + type: UPDATE_SETTINGS, + settings: settings, + } +} +export const storeUpdatePagesList = (customPages: ICustomPages[]) => { + return { + type: SET_PAGES_LIST, + customPages: customPages, + } +} +export const storeSetMixerOnline = ( + mixerIndex: number, + mixerOnline: boolean +) => { + return { + type: SET_MIXER_ONLINE, + mixerIndex: mixerIndex, + mixerOnline: mixerOnline, + } +} +export const storeSetServerOnline = (serverOnline: boolean) => { + return { + type: SET_SERVER_ONLINE, + serverOnline: serverOnline, + } +} +export const storeSetPage = (pageType: PageType, id: number | string) => { + if (typeof id === 'string') { + return { + type: SET_PAGE, + pageType: pageType, + id: id, + start: 0, + } + } else { + return { + type: SET_PAGE, + pageType: pageType, + id: '', + start: id, + } + } +} diff --git a/shared/src/actions/utils/dbConversion.ts b/shared/src/actions/utils/dbConversion.ts new file mode 100644 index 00000000..5278b85e --- /dev/null +++ b/shared/src/actions/utils/dbConversion.ts @@ -0,0 +1,46 @@ +import { VuLabelConversionType } from '../../constants/MixerProtocolInterface' + +export const Conversions = { + [VuLabelConversionType.Decibel]: { + to: (f: number): number => { + if (f >= 0.5) { + return f * 40 - 30 // max dB value: +10. + } else if (f >= 0.25) { + return f * 80 - 50 + } else if (f >= 0.0625) { + return f * 160 - 70 + } else if (f > 0.0) { + return f * 480 - 90 // min dB value: -90 or -oo + } else { + return -Infinity + } + }, + from: (d: number): number => { + let f: number + if (d < -60) { + f = (d + 90) / 480 + } else if (d < -30) { + f = (d + 70) / 160 + } else if (d < -10) { + f = (d + 50) / 80 + } else if (d <= 10) { + f = (d + 30) / 40 + } else { + f = 1 + } + return Math.max(0, f) + }, + }, + [VuLabelConversionType.DecibelRuby]: { + to: (f: number): number => + Math.max(Conversions[VuLabelConversionType.Decibel].to(f), -191), + from: (d: number): number => + Conversions[VuLabelConversionType.Decibel].from(d), + }, + [VuLabelConversionType.DecibelMC2]: { + to: (f: number): number => + Math.max(Conversions[VuLabelConversionType.Decibel].to(f), -128), + from: (d: number): number => + Conversions[VuLabelConversionType.Decibel].from(d), + }, +} diff --git a/server/constants/AutomationPresets.ts b/shared/src/constants/AutomationPresets.ts similarity index 60% rename from server/constants/AutomationPresets.ts rename to shared/src/constants/AutomationPresets.ts index 4ae0de82..f4bf2e04 100644 --- a/server/constants/AutomationPresets.ts +++ b/shared/src/constants/AutomationPresets.ts @@ -1,121 +1,120 @@ -//While developing mixer specific settings will be in one file. -//At first release these will be in seperate files -//So it´s easy to add new equipment. - -export interface IAutomationProtocol { - protocol: string, - label: string, - mode: string, - leadingZeros: boolean, - initializeCommands: [ - { - mixerMessage: string, - value: string, - type: string - } - ], - fromAutomation: { - CHANNEL_PGM_ON_OFF: string, - CHANNEL_PST_ON_OFF: string, - CHANNEL_FADER_LEVEL: string, - INJECT_COMMAND: string, - CHANNEL_VISIBLE: string, - CHANNEL_MUTE: string, - X_MIX: string, - SET_LABEL: string, - FADE_TO_BLACK: string, - CLEAR_PST: string, - SNAP_RECALL: string, - STATE_CHANNEL_PGM: string, - STATE_CHANNEL_PST: string, - STATE_CHANNEL_FADER_LEVEL: string, - STATE_CHANNEL_MUTE: string, - STATE_FULL: string - PING: string - }, - toAutomation: { - STATE_CHANNEL_PGM: string, - STATE_CHANNEL_PST: string, - STATE_CHANNEL_FADER_LEVEL: string, - STATE_CHANNEL_MUTE: string, - STATE_FULL: string, - PONG: string - }, - fader: { - min: number, - max: number, - zero: number, - step: number, - }, - meter: { - min: number, - max: number, - zero: number, - test: number, - }, -} - - -export const AutomationPresets: { [key: string]: IAutomationProtocol } = { - - sofie: { - protocol: 'OSC', - label: 'Sofie Automation', - mode: "client", - leadingZeros: true, - initializeCommands: [ - { - mixerMessage: "/info", - value: "", - type: "f" - } - ], - fromAutomation: { - CHANNEL_PGM_ON_OFF: '/ch/{value1}/pgm', - CHANNEL_PST_ON_OFF: '/ch/{value1}/pst', - CHANNEL_FADER_LEVEL: '/ch/{value1}/faderlevel', - CHANNEL_VISIBLE: '/ch/{value1}/visible', - CHANNEL_MUTE: '/ch/{value1}/mute', - X_MIX: '/take', - INJECT_COMMAND: '/inject', - SET_LABEL: '/ch/{value1}/label', - FADE_TO_BLACK: '/fadetoblack', - CLEAR_PST: '/clearpst', - SNAP_RECALL: '/snap/{value1}', - STATE_CHANNEL_PGM: '/state/ch/{value1}/pgm', - STATE_CHANNEL_PST: '/state/ch/{value1}/pst', - STATE_CHANNEL_FADER_LEVEL: '/state/ch/{value1}/faderlevel', - STATE_CHANNEL_MUTE: '/state/ch/{value1}/mute', - STATE_FULL: '/state/full', - PING: '/ping/{value1}' - }, - toAutomation: { - STATE_CHANNEL_PGM: '/state/ch/{value1}/pgm', - STATE_CHANNEL_PST: '/state/ch/{value1}/pst', - STATE_CHANNEL_FADER_LEVEL: '/state/ch/{value1}/faderlevel', - STATE_CHANNEL_MUTE: '/state/ch/{value1}/mute', - STATE_FULL: '/state/full', - PONG: '/pong' - }, - fader: { - min: 0, - max: 1, - zero: 0.75, - step: 0.01, - }, - meter: { - min: 0, - max: 1, - zero: 0.75, - test: 0.6, - }, - } -}; - - -export const AutomationProtocolList = Object.getOwnPropertyNames(AutomationPresets).map((preset) => { - return { - value: preset, - label: AutomationPresets[preset].label - }; -}); +//While developing mixer specific settings will be in one file. +//At first release these will be in seperate files +//So it´s easy to add new equipment. + +export interface IAutomationProtocol { + protocol: string + label: string + mode: string + leadingZeros: boolean + initializeCommands: [ + { + mixerMessage: string + value: string + type: string + } + ] + fromAutomation: { + CHANNEL_PGM_ON_OFF: string + CHANNEL_PST_ON_OFF: string + CHANNEL_FADER_LEVEL: string + INJECT_COMMAND: string + CHANNEL_VISIBLE: string + CHANNEL_MUTE: string + X_MIX: string + SET_LABEL: string + FADE_TO_BLACK: string + CLEAR_PST: string + SNAP_RECALL: string + STATE_CHANNEL_PGM: string + STATE_CHANNEL_PST: string + STATE_CHANNEL_FADER_LEVEL: string + STATE_CHANNEL_MUTE: string + STATE_FULL: string + PING: string + } + toAutomation: { + STATE_CHANNEL_PGM: string + STATE_CHANNEL_PST: string + STATE_CHANNEL_FADER_LEVEL: string + STATE_CHANNEL_MUTE: string + STATE_FULL: string + PONG: string + } + fader: { + min: number + max: number + zero: number + step: number + } + meter: { + min: number + max: number + zero: number + test: number + } +} + +export const AutomationPresets: { [key: string]: IAutomationProtocol } = { + sofie: { + protocol: 'OSC', + label: 'Sofie Automation', + mode: 'client', + leadingZeros: true, + initializeCommands: [ + { + mixerMessage: '/info', + value: '', + type: 'f', + }, + ], + fromAutomation: { + CHANNEL_PGM_ON_OFF: '/ch/{value1}/pgm', + CHANNEL_PST_ON_OFF: '/ch/{value1}/pst', + CHANNEL_FADER_LEVEL: '/ch/{value1}/faderlevel', + CHANNEL_VISIBLE: '/ch/{value1}/visible', + CHANNEL_MUTE: '/ch/{value1}/mute', + X_MIX: '/take', + INJECT_COMMAND: '/inject', + SET_LABEL: '/ch/{value1}/label', + FADE_TO_BLACK: '/fadetoblack', + CLEAR_PST: '/clearpst', + SNAP_RECALL: '/snap/{value1}', + STATE_CHANNEL_PGM: '/state/ch/{value1}/pgm', + STATE_CHANNEL_PST: '/state/ch/{value1}/pst', + STATE_CHANNEL_FADER_LEVEL: '/state/ch/{value1}/faderlevel', + STATE_CHANNEL_MUTE: '/state/ch/{value1}/mute', + STATE_FULL: '/state/full', + PING: '/ping/{value1}', + }, + toAutomation: { + STATE_CHANNEL_PGM: '/state/ch/{value1}/pgm', + STATE_CHANNEL_PST: '/state/ch/{value1}/pst', + STATE_CHANNEL_FADER_LEVEL: '/state/ch/{value1}/faderlevel', + STATE_CHANNEL_MUTE: '/state/ch/{value1}/mute', + STATE_FULL: '/state/full', + PONG: '/pong', + }, + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, + }, +} + +export const AutomationProtocolList = Object.getOwnPropertyNames( + AutomationPresets +).map((preset) => { + return { + value: preset, + label: AutomationPresets[preset].label, + } +}) diff --git a/shared/src/constants/MixerProtocolInterface.ts b/shared/src/constants/MixerProtocolInterface.ts new file mode 100644 index 00000000..1c8283a4 --- /dev/null +++ b/shared/src/constants/MixerProtocolInterface.ts @@ -0,0 +1,193 @@ +export enum fxParamsList { + EqGain01, + EqGain02, + EqGain03, + EqGain04, + EqFreq01, + EqFreq02, + EqFreq03, + EqFreq04, + EqQ01, + EqQ02, + EqQ03, + EqQ04, + DelayTime, + GainTrim, + CompThrs, + CompRatio, + CompKnee, + CompMakeUp, + CompAttack, + CompHold, + CompRelease, + CompOnOff, +} +export enum VuLabelConversionType { + Linear = 'linear', + Decibel = 'decibel', + DecibelRuby = 'decibelRuby', + DecibelMC2 = 'decibelMC2', +} +export interface IMixerProtocolGeneric { + protocol: string + fxList?: {} + label: string + presetFileExtension?: string + loadPresetCommand?: Array + MAX_UPDATES_PER_SECOND: number + vuLabelConversionType?: VuLabelConversionType + vuLabelValues?: Array + fader?: { + min: number + max: number + zero: number + step: number + } + meter?: { + min: number + max: number + zero: number + test: number + } + channelTypes: Array +} + +export interface IMixerProtocol extends IMixerProtocolGeneric { + leadingZeros?: boolean + pingCommand?: Array // Simple command for pinging Audio mixer + pingResponseCommand?: Array // Ping commands that expects responses + pingTime?: number // How often should mixer ping the pingCommands + mixerTimeout?: number // Max time between responses from AudioMixer + initializeCommands?: Array +} + +export interface IChannelTypes { + channelTypeName: string + channelTypeColor: string + fromMixer: { + CHANNEL_INPUT_GAIN?: Array + CHANNEL_INPUT_SELECTOR?: Array + CHANNEL_OUT_GAIN?: Array + CHANNEL_VU?: Array + CHANNEL_VU_REDUCTION?: Array + CHANNEL_NAME?: Array + PFL?: Array + NEXT_SEND?: Array + [FX_PARAM: number]: Array + AUX_LEVEL?: Array + CHANNEL_MUTE_ON?: Array + CHANNEL_MUTE_OFF?: Array + CHANNEL_AMIX?: Array + } + toMixer: { + CHANNEL_INPUT_GAIN?: Array + CHANNEL_INPUT_SELECTOR?: Array + CHANNEL_OUT_GAIN?: Array + CHANNEL_NAME?: Array + PFL_ON?: Array + PFL_OFF?: Array + NEXT_SEND?: Array + [FX_PARAM: number]: Array + AUX_LEVEL?: Array + CHANNEL_MUTE_ON?: Array + CHANNEL_MUTE_OFF?: Array + CHANNEL_AMIX?: Array + } +} + +interface IMixerMessageProtocol { + mixerMessage: string + value?: any + type?: string + min?: number + max?: number + zero?: number + label?: string + valueAsLabels?: Array + valueLabel?: string + minLabel?: number + maxLabel?: number + zeroLabel?: number +} + +export interface IFxProtocol { + key: fxParamsList + params: Array +} + +export const emptyMixerMessage = (): IMixerMessageProtocol => { + return { + mixerMessage: 'none', + value: 0, + type: '', + min: 0, + max: 0, + zero: 0, + } +} + +// CasparCG Specific interfaces: +export interface ICasparCGChannelLayerPair { + channel: number + layer: number +} + +export interface ICasparCGMixerGeometryFile { + label?: string + channelLabels?: string[] + fromMixer: { + CHANNEL_VU: Array + } + toMixer: { + PGM_CHANNEL_FADER_LEVEL: Array + PFL_AUX_FADER_LEVEL: Array + NEXT_AUX_FADER_LEVEL: Array + CHANNEL_INPUT_SELECTOR?: Array + } + sourceOptions?: { + sources: Array< + ICasparCGChannelLayerPair & { + producer: string + file: string + } + > + options: { + [key: string]: { + // producer property invocation + [key: string]: string // label: property + } + } + } +} + +export interface ICasparCGMixerGeometry extends IMixerProtocolGeneric { + studio: string + leadingZeros: boolean + pingTime: number + fromMixer: { + // CHANNEL_FADER_LEVEL: ChannelLayerPair[], + // CHANNEL_OUT_GAIN: ChannelLayerPair[], + CHANNEL_VU: Array + } + toMixer: { + PGM_CHANNEL_FADER_LEVEL: Array + PFL_AUX_FADER_LEVEL: Array + NEXT_AUX_FADER_LEVEL: Array + CHANNEL_INPUT_SELECTOR?: Array + } + channelLabels?: string[] + sourceOptions?: { + sources: Array< + ICasparCGChannelLayerPair & { + producer: string + file: string + } + > + options: { + [key: string]: { + // producer property invocation + [key: string]: string // label: property + } + } + } +} diff --git a/shared/src/constants/MixerProtocolPresets.ts b/shared/src/constants/MixerProtocolPresets.ts new file mode 100644 index 00000000..28f6cfba --- /dev/null +++ b/shared/src/constants/MixerProtocolPresets.ts @@ -0,0 +1,55 @@ +import { ArdourMaster } from './mixerProtocols/ardourMaster' +import { ReaperMaster } from './mixerProtocols/reaperMaster' +import { BehringerXrMaster } from './mixerProtocols/behringerXrMaster' +import { MidasMaster } from './mixerProtocols/midasMaster' +import { GenericMidi } from './mixerProtocols/genericMidi' +import { LawoRelayVrx4 } from './mixerProtocols/LawoRelayVrx4' +import { LawoMC2 } from './mixerProtocols/LawoMC2' +import { LawoRuby } from './mixerProtocols/LawoRuby' +import { CasparCGMaster } from './mixerProtocols/casparCGMaster' +import { DMXIS } from './mixerProtocols/DmxIs' +import { YamahaQLCL } from './mixerProtocols/yamahaQLCL' +import { SSLSystemT } from './mixerProtocols/SSLsystemT' +import { StuderOnAirMaster } from './mixerProtocols/StuderOnAirEmber' +import { StuderVistaMaster } from './mixerProtocols/StuderVistaEmber' +import { VMix } from './mixerProtocols/vMix' +import { Atem } from './mixerProtocols/atem' + +// Interface: +import { IMixerProtocolGeneric } from './MixerProtocolInterface' + +export const MixerProtocolPresets: { + [key: string]: IMixerProtocolGeneric +} = Object.assign( + { + ardourMaster: ArdourMaster, + reaperMaster: ReaperMaster, + behringerxrmaster: BehringerXrMaster, + midasMaster: MidasMaster, + genericMidi: GenericMidi, + lawoRelayVrx4: LawoRelayVrx4, + lawoMC2: LawoMC2, + lawoRuby: LawoRuby, + dmxis: DMXIS, + yamahaQlCl: YamahaQLCL, + sslSystemT: SSLSystemT, + studerOnAirMaster: StuderOnAirMaster, + studerVistaMaster: StuderVistaMaster, + vMix: VMix, + atem: Atem, + }, + { + casparCGMaster: CasparCGMaster, + } +) +/* + */ + +export const MixerProtocolList = Object.getOwnPropertyNames( + MixerProtocolPresets +).map((preset) => { + return { + value: preset, + label: MixerProtocolPresets[preset].label, + } +}) diff --git a/server/constants/SOCKET_IO_DISPATCHERS.ts b/shared/src/constants/SOCKET_IO_DISPATCHERS.ts similarity index 58% rename from server/constants/SOCKET_IO_DISPATCHERS.ts rename to shared/src/constants/SOCKET_IO_DISPATCHERS.ts index 9398ef36..aabd9851 100644 --- a/server/constants/SOCKET_IO_DISPATCHERS.ts +++ b/shared/src/constants/SOCKET_IO_DISPATCHERS.ts @@ -1,41 +1,49 @@ -// Dispatch constants: - -// Fader Channels: -export const SOCKET_SET_FADERLEVEL = 'FaderLevel' -export const SOCKET_SET_ASSIGNED_FADER = 'setAssignedFader' -export const SOCKET_SET_FADER_MONITOR = 'FaderMonitor' -export const SOCKET_SET_AUX_LEVEL = 'setAuxLevel' -export const SOCKET_SET_INPUT_OPTION = 'setInputOption' -export const SOCKET_SET_THRESHOLD = 'setThreshold' -export const SOCKET_SET_RATIO = 'setRatio' -export const SOCKET_SET_DELAY_TIME = 'setDelayTime' -export const SOCKET_SET_LOW = 'setLow' -export const SOCKET_SET_LO_MID = 'setLoMid' -export const SOCKET_SET_MID = 'setMid' -export const SOCKET_SET_HIGH = 'setHigh' -export const SOCKET_TOGGLE_PGM = 'togglePgm' -export const SOCKET_TOGGLE_VO = 'toggleVo' -export const SOCKET_TOGGLE_PST = 'togglePst' -export const SOCKET_TOGGLE_PFL = 'togglePfl' -export const SOCKET_TOGGLE_MUTE = 'toggleMute' -export const SOCKET_TOGGLE_IGNORE = 'toggleIgnore' -export const SOCKET_NEXT_MIX = 'nextMix' -export const SOCKET_CLEAR_PST = 'clearPst' - - -// Div: -export const SOCKET_SAVE_SETTINGS = 'saveSettings' -export const SOCKET_RESTART_SERVER = 'restartServer' -export const SOCKET_SET_VU = 'setVu' -export const SOCKET_GET_SNAPSHOT_LIST = 'getSnapshotList' -export const SOCKET_RETURN_SNAPSHOT_LIST = 'returnSnapshotList' -export const SOCKET_GET_CCG_LIST = 'getCcgList' -export const SOCKET_RETURN_CCG_LIST = 'returnCcgList' -export const SOCKET_LOAD_SNAPSHOT = 'loadSnapshot' -export const SOCKET_SAVE_SNAPSHOT = 'saveSnapshot' -export const SOCKET_SAVE_CCG_FILE = 'saveCcgFile' - -// Store updates: -export const SOCKET_SET_FULL_STORE = 'setFullStore' -export const SOCKET_SET_STORE_FADER = 'setStoreFader' -export const SOCKET_SET_STORE_CHANNEL = 'setStoreChannel' +// Dispatch constants: + +// Fader Channels: +export const SOCKET_SET_FADERLEVEL = 'FaderLevel' +export const SOCKET_SET_INPUT_GAIN = 'InputGain' +export const SOCKET_SET_INPUT_SELECTOR = 'InputSelector' +export const SOCKET_SET_ASSIGNED_FADER = 'setAssignedFader' +export const SOCKET_SET_FADER_MONITOR = 'FaderMonitor' +export const SOCKET_SHOW_IN_MINI_MONITOR = 'showInMiniMonitor' +export const SOCKET_SET_AUX_LEVEL = 'setAuxLevel' +export const SOCKET_SET_INPUT_OPTION = 'setInputOption' +export const SOCKET_SET_FX = 'setHigh' +export const SOCKET_TOGGLE_PGM = 'togglePgm' +export const SOCKET_TOGGLE_VO = 'toggleVo' +export const SOCKET_TOGGLE_SLOW_FADE = 'toggleSlowFade' +export const SOCKET_TOGGLE_PST = 'togglePst' +export const SOCKET_TOGGLE_PFL = 'togglePfl' +export const SOCKET_TOGGLE_MUTE = 'toggleMute' +export const SOCKET_TOGGLE_AMIX = 'toggleAmix' +export const SOCKET_TOGGLE_IGNORE = 'toggleIgnore' +export const SOCKET_NEXT_MIX = 'nextMix' +export const SOCKET_CLEAR_PST = 'clearPst' + +// Div: +export const SOCKET_SAVE_SETTINGS = 'saveSettings' +export const SOCKET_RESTART_SERVER = 'restartServer' +export const SOCKET_GET_SNAPSHOT_LIST = 'getSnapshotList' +export const SOCKET_RETURN_SNAPSHOT_LIST = 'returnSnapshotList' +export const SOCKET_GET_CCG_LIST = 'getCcgList' +export const SOCKET_RETURN_CCG_LIST = 'returnCcgList' +export const SOCKET_GET_MIXER_PRESET_LIST = 'getMixerPresetList' +export const SOCKET_RETURN_MIXER_PRESET_LIST = 'returnMixerPresetList' +export const SOCKET_LOAD_MIXER_PRESET = 'loadMixerPreset' +export const SOCKET_LOAD_SNAPSHOT = 'loadSnapshot' +export const SOCKET_SAVE_SNAPSHOT = 'saveSnapshot' +export const SOCKET_SAVE_CCG_FILE = 'saveCcgFile' +export const SOCKET_GET_PAGES_LIST = 'getPagesList' +export const SOCKET_RETURN_PAGES_LIST = 'getPagesList' +export const SOCKET_TOGGLE_ALL_MANUAL = 'toggleAllManual' +export const SOCKET_GET_LABELS = 'getLabels' + +// Store updates: +export const SOCKET_SET_FULL_STORE = 'setFullStore' +export const SOCKET_SET_STORE_FADER = 'setStoreFader' +export const SOCKET_SET_STORE_CHANNEL = 'setStoreChannel' +export const SOCKET_SET_MIXER_ONLINE = 'setStoreSettings' +export const SOCKET_SET_PAGES_LIST = 'setPagesList' +export const SOCKET_SET_LABELS = 'setLabels' +export const SOCKET_FLUSH_LABELS = 'flushLabels' diff --git a/shared/src/constants/mixerProtocols/DmxIs.ts b/shared/src/constants/mixerProtocols/DmxIs.ts new file mode 100644 index 00000000..1c56a930 --- /dev/null +++ b/shared/src/constants/mixerProtocols/DmxIs.ts @@ -0,0 +1,62 @@ +import { IMixerProtocol } from '../MixerProtocolInterface' + +export const DMXIS: IMixerProtocol = { + protocol: 'OSC', + label: 'DMXIS Light Controller Protocol', + presetFileExtension: '', + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. + pingTime: 0, //Bypass ping when pingTime is zero + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#3f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/dmxis/ch/{channel}', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/dmxis/ch/{channel}', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '/dmxis/ch/name/{channel}', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/LawoMC2.ts b/shared/src/constants/mixerProtocols/LawoMC2.ts new file mode 100644 index 00000000..b5f0f9cf --- /dev/null +++ b/shared/src/constants/mixerProtocols/LawoMC2.ts @@ -0,0 +1,203 @@ +import { + IMixerProtocol, + emptyMixerMessage, + VuLabelConversionType, +} from '../MixerProtocolInterface' + +export const LawoMC2: IMixerProtocol = { + protocol: 'EMBER', + label: 'Lawo MC2', + presetFileExtension: 'MC2', + loadPresetCommand: [ + { + mixerMessage: 'Production.Load Snapshot', + }, + ], + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. + pingCommand: [emptyMixerMessage()], + pingResponseCommand: [emptyMixerMessage()], + pingTime: 0, //Bypass ping when pingTime is zero + initializeCommands: [emptyMixerMessage()], + vuLabelConversionType: VuLabelConversionType.DecibelMC2, + vuLabelValues: [0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'Channels.Inputs.${channel}.Fader.Fader Level', + value: 0, + type: 'real', + min: -128, + max: 12, + zero: 0, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: + 'Channels.Inputs.${channel}.General.User Label', + value: 0, + type: 'real', + min: -200, + max: 20, + zero: 0, + }, + ], + CHANNEL_INPUT_GAIN: [ + { + mixerMessage: + 'Channels.Inputs.${channel}.Signal Processing.Digital Amplifier.DigiAmp Level', + value: 0, + type: 'int', + min: -128, + max: 12, + zero: 0, + maxLabel: 12, + minLabel: -128, + }, + ], + CHANNEL_INPUT_SELECTOR: [ + { + mixerMessage: + 'Channels.Inputs.${channel}.Signal Processing.Input Mixer.Input Left to Both', + value: 0, + type: 'bool', + label: 'LR', + }, + { + mixerMessage: + 'Channels.Inputs.${channel}.Signal Processing.Input Mixer.Input Left to Both', + value: true, + type: 'bool', + label: 'LL', + }, + { + mixerMessage: + 'Channels.Inputs.${channel}.Signal Processing.Input Mixer.Input Right to Both', + value: true, + type: 'bool', + label: 'RR', + }, + ], + PFL: [ + { + mixerMessage: 'Channels.Inputs.${channel}.Listen.PFL', + value: 0, + type: 'boolean', + min: -128, + max: 12, + zero: 0, + }, + ], + CHANNEL_AMIX: [ + { + mixerMessage: + 'Channels.Inputs.${channel}.Automix.Automix Active', + value: false, + type: 'boolean', + min: -128, + max: 12, + zero: 0, + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'Channels.Inputs.${channel}.Fader.Fader Level', + value: 0, + type: 'real', + min: -128, + max: 12, + zero: 0, + }, + ], + CHANNEL_INPUT_GAIN: [ + { + mixerMessage: + 'Channels.Inputs.${channel}.Signal Processing.Digital Amplifier.DigiAmp Level', + value: 0, + type: 'int', + min: -128, + max: 12, + zero: 0, + maxLabel: 12, + minLabel: -128, + }, + ], + CHANNEL_INPUT_SELECTOR: [ + { + mixerMessage: + 'Channels.Inputs.${channel}.Signal Processing.Input Mixer.Input Left to Both', + value: 0, + type: 'bool', + label: 'LR', + }, + { + mixerMessage: + 'Channels.Inputs.${channel}.Signal Processing.Input Mixer.Input Left to Both', + value: 1, + type: 'bool', + label: 'LL', + }, + { + mixerMessage: + 'Channels.Inputs.${channel}.Signal Processing.Input Mixer.Input Right to Both', + value: 1, + type: 'bool', + label: 'RR', + }, + ], + PFL_ON: [ + { + mixerMessage: 'Channels.Inputs.${channel}.Listen.PFL', + value: true, + type: 'boolean', + min: -128, + max: 12, + zero: 0, + }, + ], + PFL_OFF: [ + { + mixerMessage: 'Channels.Inputs.${channel}.Listen.PFL', + value: false, + type: 'boolean', + min: -128, + max: 12, + zero: 0, + }, + ], + CHANNEL_AMIX: [ + { + mixerMessage: + 'Channels.Inputs.${channel}.Automix.Automix Active', + value: false, + type: 'boolean', + min: -128, + max: 12, + zero: 0, + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 10, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/LawoRelayVrx4.ts b/shared/src/constants/mixerProtocols/LawoRelayVrx4.ts new file mode 100644 index 00000000..5a009920 --- /dev/null +++ b/shared/src/constants/mixerProtocols/LawoRelayVrx4.ts @@ -0,0 +1,91 @@ +import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface' + +export const LawoRelayVrx4: IMixerProtocol = { + protocol: 'EMBER', + label: 'Lawo Relay VRX4 - client', + presetFileExtension: '', + loadPresetCommand: [emptyMixerMessage()], + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. + pingCommand: [emptyMixerMessage()], + pingResponseCommand: [emptyMixerMessage()], + pingTime: 0, //Bypass ping when pingTime is zero + initializeCommands: [emptyMixerMessage()], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'R3LAYVRX4/Ex/GUI/FaderSlot_{channel}/FaderPosition', + value: 0, + type: 'real', + min: 0, + max: 100, + zero: 75, + }, + ], + CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], + CHANNEL_NAME: [ + { + mixerMessage: '', + value: 0, + type: 'real', + min: -200, + max: 20, + zero: 0, + }, + ], + PFL: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [emptyMixerMessage()], + CHANNEL_MUTE_OFF: [emptyMixerMessage()], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'R3LAYVRX4/Ex/GUI/FaderSlot_{channel}/FaderPosition', + value: 0, + type: 'real', + min: 0, + max: 100, + zero: 0, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '', + value: 0, + type: 'real', + min: -200, + max: 20, + zero: 0, + }, + ], + PFL_ON: [emptyMixerMessage()], + PFL_OFF: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [emptyMixerMessage()], + CHANNEL_MUTE_OFF: [emptyMixerMessage()], + }, + }, + ], + fader: { + min: 0, + max: 200, + zero: 1300, + step: 10, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/LawoRuby.ts b/shared/src/constants/mixerProtocols/LawoRuby.ts new file mode 100644 index 00000000..a559aac7 --- /dev/null +++ b/shared/src/constants/mixerProtocols/LawoRuby.ts @@ -0,0 +1,174 @@ +import { + IMixerProtocol, + emptyMixerMessage, + VuLabelConversionType, +} from '../MixerProtocolInterface' + +export const LawoRuby: IMixerProtocol = { + protocol: 'LAWORUBY', + label: 'Lawo Ruby', + presetFileExtension: '', + loadPresetCommand: [emptyMixerMessage()], + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. + pingCommand: [emptyMixerMessage()], + pingResponseCommand: [emptyMixerMessage()], + pingTime: 0, //Bypass ping when pingTime is zero + initializeCommands: [emptyMixerMessage()], + vuLabelConversionType: VuLabelConversionType.Decibel, + vuLabelValues: [0, 0.5, 0.75, 1], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_INPUT_GAIN: [ + { + mixerMessage: + 'Ruby.Sources.{channel}.DSP.Input.Gain[dB]', + value: 0, + type: 'int', + min: -30, + max: 18, + zero: 0, + }, + ], + CHANNEL_INPUT_SELECTOR: [ + { + mixerMessage: + 'Ruby.Sources.{channel}.DSP.Input.LR Mode', + value: 0, + type: 'int', + label: 'LR', + }, + { + mixerMessage: + 'Ruby.Sources.{channel}.DSP.Input.LR Mode', + value: 4, + type: 'int', + label: 'LL', + }, + { + mixerMessage: + 'Ruby.Sources.{channel}.DSP.Input.LR Mode', + value: 1, + type: 'int', + label: 'RR', + }, + ], + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'Ruby.Sources.{channel}.Fader.Motor dB Value', + value: 0, + type: 'int', + min: -191, + max: 9, + zero: 0.75, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '', + value: 0, + type: 'real', + min: -200, + max: 20, + zero: 0, + }, + ], + PFL: [emptyMixerMessage()], + CHANNEL_AMIX: [ + { + mixerMessage: 'Ruby.Sources.{channel}.DSP.AutoMix.On', + }, + ], + }, + toMixer: { + CHANNEL_INPUT_GAIN: [ + { + mixerMessage: + 'Ruby.Sources.{channel}.DSP.Input.Gain[dB]', + value: 0, + type: 'int', + min: -30, + max: 18, + zero: 0, + }, + ], + CHANNEL_INPUT_SELECTOR: [ + { + mixerMessage: + 'Ruby.Sources.{channel}.DSP.Input.LR Mode', + value: 0, + type: 'int', + label: 'LR', + }, + { + mixerMessage: + 'Ruby.Sources.{channel}.DSP.Input.LR Mode', + value: 4, + type: 'int', + label: 'LL', + }, + { + mixerMessage: + 'Ruby.Sources.{channel}.DSP.Input.LR Mode', + value: 1, + type: 'int', + label: 'RR', + }, + ], + CHANNEL_OUT_GAIN: [ + // { + // mixerMessage: + // 'Ruby.Sources.{channel}.Fader.Motor Position', + // value: 0, + // type: 'int', + // min: 0, + // max: 255, + // zero: 204, + // }, + { + mixerMessage: + 'Ruby.Sources.{channel}.Fader.Motor dB Value', + value: 0, + type: 'int', + min: -191, + max: 9, + zero: 0, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '', + value: 0, + type: 'real', + min: -200, + max: 20, + zero: 0, + }, + ], + PFL_ON: [emptyMixerMessage()], + PFL_OFF: [emptyMixerMessage()], + CHANNEL_AMIX: [ + { + mixerMessage: 'Ruby.Sources.{channel}.DSP.AutoMix.On', + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 255, + zero: 0.75, + step: 5, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/SSLsystemT.ts b/shared/src/constants/mixerProtocols/SSLsystemT.ts new file mode 100644 index 00000000..e791f11b --- /dev/null +++ b/shared/src/constants/mixerProtocols/SSLsystemT.ts @@ -0,0 +1,76 @@ +import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface' + +export const SSLSystemT: IMixerProtocol = { + protocol: 'SSL', + label: 'SSL System T', + presetFileExtension: '', + loadPresetCommand: [emptyMixerMessage()], + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, + pingCommand: [emptyMixerMessage()], + pingResponseCommand: [emptyMixerMessage()], + pingTime: 5000, + initializeCommands: [ + { + mixerMessage: 'f1 04 00 00 00 {channel}', + }, + ], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [emptyMixerMessage()], // Handled by SSLMixerconnection + CHANNEL_MUTE_ON: [ + { + mixerMessage: 'f1 04 00 01 00 {channel}', + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: 'f1 06 00 80 00 {channel} {level}', + }, + ], + PFL_ON: [ + { + mixerMessage: 'f1 05 00 80 05 {channel} 01', + }, + ], + PFL_OFF: [ + { + mixerMessage: 'f1 05 00 80 05 {channel} 00', + }, + ], + NEXT_SEND: [ + { + mixerMessage: 'f1 06 00 80 00 {channel} {level}', + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: 'f1 05 00 80 01 {channel} 00', + }, + ], + CHANNEL_MUTE_OFF: [ + { + mixerMessage: 'f1 05 00 80 01 {channel} 01', + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/StuderOnAirEmber.ts b/shared/src/constants/mixerProtocols/StuderOnAirEmber.ts new file mode 100644 index 00000000..79682acf --- /dev/null +++ b/shared/src/constants/mixerProtocols/StuderOnAirEmber.ts @@ -0,0 +1,202 @@ +import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface' + +export const StuderOnAirMaster: IMixerProtocol = { + protocol: 'STUDER', + label: 'Studer OnAir 3000', + presetFileExtension: '', + loadPresetCommand: [emptyMixerMessage()], + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. + pingCommand: [emptyMixerMessage()], + pingResponseCommand: [emptyMixerMessage()], + pingTime: 0, //Bypass ping when pingTime is zero + initializeCommands: [emptyMixerMessage()], + channelTypes: [ + { + channelTypeName: 'MONO', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp Mono/Inp Mono #{channel}/Functions/Fader/Value', + value: 0, + type: 'real', + min: 0, + max: 1000, + zero: 0, + }, + ], + CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], + CHANNEL_NAME: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp Mono/Inp Mono #{channel}/Functions/Channel Attribute/User Label', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + PFL: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [emptyMixerMessage()], + CHANNEL_MUTE_OFF: [emptyMixerMessage()], + }, + // Ch 1: Max level : + // 7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 a1 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 03 e8 00 00 00 00 + // Ch 2: Min level : + /* +C1: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 a1 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + + +C2: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 a2 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + + +C4: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 a4 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + + +C5: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 a5 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + + +C9: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 a9 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + + +C10: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 aa 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + +C15: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 af 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + +C16: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 b0 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + + +C17: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 b1 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + + +C23: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 b7 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + + +C24: +7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 b8 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 01 4a 00 00 00 00 + +C31: +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 1f 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 12 00 00 00 00 +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 1f 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 ee 00 00 00 00 + +C32: +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 20 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 12 00 00 00 00 + +C32: +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 21 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 12 00 00 00 00 +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 21 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 00 00 00 00 00 00 + +testtool: +0000 00 d8 61 3f 19 1c 00 d8 61 47 56 eb 08 00 45 00 +0010 00 50 66 c6 40 00 80 06 12 88 c0 a8 00 05 c0 a8 +0020 00 04 e9 13 1d b0 cb 35 a7 04 eb f8 11 6c 50 18 +0030 20 12 41 e8 00 00 7f 8f ff fe d9 5c 80 30 80 a4 +0040 19 31 17 a1 15 31 13 bf 20 10 31 0e a6 0c 31 0a +0050 e1 08 31 06 63 04 02 02 03 20 00 00 00 00 + +0000 00 d8 61 3f 19 1c 00 d8 61 47 56 eb 08 00 45 00 +0010 00 50 67 04 40 00 80 06 12 4a c0 a8 00 05 c0 a8 +0020 00 04 ea 5e 1d b0 01 3d 11 88 f9 2a 39 99 50 18 +0030 20 14 6b 29 00 00 7f 8f ff fe d9 5c 80 30 80 a4 +0040 19 31 17 a1 15 31 13 bf 20 10 31 0e a6 0c 31 0a +0050 e1 08 31 06 63 04 02 02 02 a8 00 00 00 00 + +sisyfos: +0000 00 d8 61 3f 19 1c 50 9f 27 8b 82 d0 08 00 45 00 +0010 00 50 00 00 40 00 37 06 b8 32 bc b0 0e 19 c0 a8 +0020 00 04 c1 2c 1d b0 07 cf 83 42 4b a4 bf a2 50 18 +0030 10 00 45 39 00 00 7f 8f ff fe d9 5c 80 30 80 a4 +0040 19 31 17 a1 15 31 13 bf 26 10 31 0e a6 0c 31 0a +0050 e1 08 31 06 63 04 02 02 00 f3 00 00 00 00 + + +CH47: +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 2f 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 12 00 00 00 00 + + +CH 48: +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 30 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 12 00 00 00 00 + +CH 71: +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 47 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 12 00 00 00 00 + +CH 72: +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 48 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 12 00 00 00 00 + +CH 95: +7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 5f 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 12 00 00 00 00 + +CH 96:7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf 60 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 02 12 00 00 00 00 + +*/ + + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a1 14 31 12 {channel} 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 {level} 00 00 00 00', // '7f 8f ff fe d9 5c 80 30 80 a4 18 31 16 a2 14 31 12 {channel} 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 {level} 00 00 00 00', + value: 0, + type: 'real', + min: 0, + max: 1000, + zero: 750, + }, + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a4 19 31 17 a1 15 31 13 bf {channel} 10 31 0e a6 0c 31 0a e1 08 31 06 63 04 02 02 {level} 00 00 00 00', + value: 0, + type: 'real', + min: 0, + max: 1000, + zero: 750, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp Mono/Inp Mono #{channel}/Functions/Channel Attribute/User Label', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + PFL_ON: [emptyMixerMessage()], + PFL_OFF: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [emptyMixerMessage()], + CHANNEL_MUTE_OFF: [emptyMixerMessage()], + }, + }, + ], + fader: { + min: 0, + max: 1000, + zero: 750, + step: 1, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/StuderVistaEmber.ts b/shared/src/constants/mixerProtocols/StuderVistaEmber.ts new file mode 100644 index 00000000..70b33720 --- /dev/null +++ b/shared/src/constants/mixerProtocols/StuderVistaEmber.ts @@ -0,0 +1,373 @@ +import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface' + +export const StuderVistaMaster: IMixerProtocol = { + protocol: 'VISTA', + label: 'Studer Vista 1-5-9', + presetFileExtension: '', + loadPresetCommand: [emptyMixerMessage()], + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. + pingCommand: [ + { + mixerMessage: '7F 8F FF FE D9 5C 80 30 80 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + { + // Subscribe to fader levels from Studer + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 25 31 23 a1 21 31 1f a1 1d 31 1b {ch-type} 19 31 17 {channel} 15 31 13 a1 11 31 0f a2 0d 31 0b e1 09 31 08 63 06 02 04 ff ff f4 c0 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + { + // Subscribe to Mute state from Studer + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 25 31 23 a1 21 31 1f a1 1d 31 1b {ch-type} 19 31 17 {channel} 15 31 13 a1 11 31 0f a2 0d 31 0b e2 09 31 08 63 06 02 04 ff ff f4 c0 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + { + // Subscribe to Aux levels from Studer + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 25 31 23 a1 21 31 1f a1 1d 31 1b {ch-type} 19 31 17 {channel} 15 31 13 a1 11 31 0f a4 0d 31 0f {aux} 0d 31 0b e1 09 31 08 63 06 02 04 ff ff f4 c0 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + pingResponseCommand: [emptyMixerMessage()], + pingTime: 6000, //Bypass ping when pingTime is zero + initializeCommands: [emptyMixerMessage()], + channelTypes: [ + { + channelTypeName: 'MONO', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: 'a1 a1 {ch-type} {channel} a1 a2 e1', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], + CHANNEL_NAME: [emptyMixerMessage()], + PFL: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [ + { + mixerMessage: 'a1 a1 {ch-type} {channel} a1 a4 {aux}', + //'7f 8f ff fe d9 5c 80 30 80 a1 25 31 23 a1 21 31 1f a1 1d 31 1b a1 19 31 17 {channel} 15 31 13 a1 11 31 0f a2 0d 31 0b e1 09 31 07 63 {level}', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: 'a1 a1 {ch-type} {channel} a1 a2 e2', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_MUTE_OFF: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 23 31 21 a1 1f 31 1d a1 1b 31 19 a1 17 31 15 {channel} 13 31 11 a1 0f 31 0d a2 0b 31 09 e2 07 31 05 63 03 02 01 00 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + // 7f 8f ff fe d9 5c 80 30 80 a1 25 31 23 a1 21 31 1f a1 1d 31 1b a1 19 31 17 {a3} 15 31 13 a1 11 31 0f a2 0d 31 0b e1 09 31 07 63 {05 09 03 c0 06 13 00 00 00 00} + mixerMessage: + // 7f 8f ff fe d9 5c 80 30 80 a1 2b 31 29 a1 27 31 25 a1 23 31 21 a1 1f 31 1d a1 1b 31 19 a1 17 31 15 a2 13 31 11 e1 0f 31 d 63 b 9 9 c0 4 1f 4c cc cc cc cc cd 0 0 0 0 + '7f 8f ff fe d9 5c 80 30 80 a1 25 31 23 a1 21 31 1f a1 1d 31 1b a1 19 31 17 {channel} 15 31 13 a1 11 31 0f a2 0d 31 0b e1 09 31 07 63 {level}', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp Mono/Inp Mono #{channel}/Functions/Channel Attribute/User Label', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + PFL_ON: [emptyMixerMessage()], + PFL_OFF: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 29 31 27 a1 25 31 23 a1 21 31 1f a1 1d 31 1b {channel} 19 31 17 a1 15 31 13 a4 11 31 0f {aux} 0d 31 0b e1 09 31 07 63 {argument}', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 23 31 21 a1 1f 31 1d a1 1b 31 19 a1 17 31 15 {channel} 13 31 11 a1 0f 31 0d a2 0b 31 09 e2 07 31 05 63 03 02 01 01 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_MUTE_OFF: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 23 31 21 a1 1f 31 1d a1 1b 31 19 a1 17 31 15 {channel} 13 31 11 a1 0f 31 0d a2 0b 31 09 e2 07 31 05 63 03 02 01 00 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + }, + }, + { + channelTypeName: 'ST', + channelTypeColor: '#3f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp Stereo/Inp Stereo #{channel}/Functions/Fader/Value', + value: 0, + type: 'real', + min: 0, + max: 1000, + zero: 750, + }, + ], + CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], + CHANNEL_NAME: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp Stereo/Inp Stereo #{channel}/Functions/Channel Attribute/User Label', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + PFL: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [emptyMixerMessage()], + CHANNEL_MUTE_OFF: [emptyMixerMessage()], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + // 7f 8f ff fe d9 5c 80 30 80 a1 25 31 23 a1 21 31 1f a1 1d 31 1b a2 19 31 17 b9 15 31 13 a1 11 31 0f a2 0d 31 0b e1 09 31 07 63 05 09 03 80 03 05 00 00 00 00 + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 25 31 23 a1 21 31 1f a1 1d 31 1b a2 19 31 17 {channel} 15 31 13 a1 11 31 0f a2 0d 31 0b e1 09 31 07 63 {level}', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp Stereo/Inp Stereo #{channel}/Functions/Channel Attribute/User Label', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + PFL_ON: [emptyMixerMessage()], + PFL_OFF: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 29 31 27 a1 25 31 23 a1 21 31 1f a2 1d 31 1b {channel} 19 31 17 a1 15 31 13 a4 11 31 0f {aux} 0d 31 0b e1 09 31 07 63 {argument}', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 23 31 21 a1 1f 31 1d a1 1b 31 19 a2 17 31 15 {channel} 13 31 11 a1 0f 31 0d a2 0b 31 09 e2 07 31 05 63 03 02 01 01 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_MUTE_OFF: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 23 31 21 a1 1f 31 1d a1 1b 31 19 a2 17 31 15 {channel} 13 31 11 a1 0f 31 0d a2 0b 31 09 e2 07 31 05 63 03 02 01 00 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + }, + }, + { + channelTypeName: 'Inp X', + channelTypeColor: '#2f3f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp 5_1/Inp 5_1 #{channel}/Functions/Fader/Value', + value: 0, + type: 'real', + min: 0, + max: 1000, + zero: 750, + }, + ], + CHANNEL_VU: [emptyMixerMessage()], + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], + CHANNEL_NAME: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp 5_1/Inp 5_1 #{channel}/Functions/Channel Attribute/User Label', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + PFL: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [emptyMixerMessage()], + CHANNEL_MUTE_OFF: [emptyMixerMessage()], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 25 31 23 a1 21 31 1f a1 1d 31 1b a3 19 31 17 {channel} 15 31 13 a1 11 31 0f a2 0d 31 0b e1 09 31 07 63 {level}', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: + 'System/Mixer/Channels/Inp 5_1/Inp 5_1 #{channel}/Functions/Channel Attribute/User Label', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + PFL_ON: [emptyMixerMessage()], + PFL_OFF: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 29 31 27 a1 25 31 23 a1 21 31 1f a3 1d 31 1b {channel} 19 31 17 a1 15 31 13 a4 11 31 0f {aux} 0d 31 0b e1 09 31 07 63 {argument}', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 23 31 21 a1 1f 31 1d a1 1b 31 19 a3 17 31 15 {channel} 13 31 11 a1 0f 31 0d a2 0b 31 09 e2 07 31 05 63 03 02 01 01 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + CHANNEL_MUTE_OFF: [ + { + mixerMessage: + '7f 8f ff fe d9 5c 80 30 80 a1 23 31 21 a1 1f 31 1d a1 1b 31 19 a3 17 31 15 {channel} 13 31 11 a1 0f 31 0d a2 0b 31 09 e2 07 31 05 63 03 02 01 00 00 00 00 00', + value: 0, + type: 'real', + min: -90, + max: 10, + zero: 0, + }, + ], + }, + }, + ], + fader: { + min: -90, + max: 10, + zero: 0, + step: 1, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/ardourMaster.ts b/shared/src/constants/mixerProtocols/ardourMaster.ts new file mode 100644 index 00000000..a9e2fd54 --- /dev/null +++ b/shared/src/constants/mixerProtocols/ardourMaster.ts @@ -0,0 +1,112 @@ +import { IMixerProtocol } from '../MixerProtocolInterface' + +export const ArdourMaster: IMixerProtocol = { + protocol: 'OSC', + label: 'Ardour DAW - Master Mode', + presetFileExtension: '', + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, + pingCommand: [ + { + mixerMessage: '/strip/list', + value: 0, + type: 'i', + min: 0, + max: 1, + zero: 0.75, + }, + ], + pingResponseCommand: [ + { + mixerMessage: '/strip/list', + value: 0, + type: 'i', + min: 0, + max: 1, + zero: 0.75, + }, + ], + pingTime: 9500, + initializeCommands: [ + { + mixerMessage: '/set_surface/feedback', + value: '135', + type: 'i', + min: 0, + max: 1, + zero: 0.75, + }, + ], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/strip/fader/{channel}', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_VU: [ + { + mixerMessage: '/strip/meter/{channel}', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '/strip/name/{channel}', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/strip/fader/{channel}', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '/strip/name/{channel}', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + meter: { + min: 0, + max: 1, + zero: 0.85, + test: 0.75, + }, +} diff --git a/shared/src/constants/mixerProtocols/atem.ts b/shared/src/constants/mixerProtocols/atem.ts new file mode 100644 index 00000000..eff192e6 --- /dev/null +++ b/shared/src/constants/mixerProtocols/atem.ts @@ -0,0 +1,82 @@ +import { + IMixerProtocol, + fxParamsList, + VuLabelConversionType, +} from '../MixerProtocolInterface' + +export const Atem: IMixerProtocol = { + MAX_UPDATES_PER_SECOND: 10, + protocol: 'ATEM', + label: 'ATEM Audio Control', + vuLabelConversionType: VuLabelConversionType.Decibel, + vuLabelValues: [0, 0.125, 0.25, 0.375, 0.5, 0.75, 1], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + channelTypes: [ + { + channelTypeName: 'Input', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_INPUT_GAIN: [ + { mixerMessage: '', maxLabel: 6, minLabel: -12 }, + ], + CHANNEL_INPUT_SELECTOR: [ + { + mixerMessage: '', + label: 'LR', + }, + { + mixerMessage: '', + label: 'LL', + }, + { + mixerMessage: '', + label: 'RR', + }, + ], + // CHANNEL_OUT_GAIN: [{ mixerMessage: '' }], + // CHANNEL_VU?: Array + // CHANNEL_VU_REDUCTION?: Array + // CHANNEL_NAME?: Array + // PFL?: Array + // NEXT_SEND?: Array + // [FX_PARAM: number]: Array + // AUX_LEVEL?: Array + // CHANNEL_MUTE_ON: [{ mixerMessage: '' }], + // CHANNEL_MUTE_OFF?: Array + // CHANNEL_AMIX?: Array + }, + toMixer: { + CHANNEL_INPUT_GAIN: [{ mixerMessage: '' }], + CHANNEL_INPUT_SELECTOR: [ + { + mixerMessage: '', + label: 'LR', + }, + { + mixerMessage: '', + label: 'LL', + }, + { + mixerMessage: '', + label: 'RR', + }, + ], + // CHANNEL_OUT_GAIN: [{ mixerMessage: '' }], + // CHANNEL_NAME?: Array + // PFL_ON?: Array + // PFL_OFF?: Array + // NEXT_SEND?: Array + // [FX_PARAM: number]: Array + // AUX_LEVEL?: Array + CHANNEL_MUTE_ON: [{ mixerMessage: '' }], + CHANNEL_MUTE_OFF: [{ mixerMessage: '' }], + // CHANNEL_AMIX?: Array + }, + }, + ], +} diff --git a/shared/src/constants/mixerProtocols/behringerXrMaster.ts b/shared/src/constants/mixerProtocols/behringerXrMaster.ts new file mode 100644 index 00000000..1863b64d --- /dev/null +++ b/shared/src/constants/mixerProtocols/behringerXrMaster.ts @@ -0,0 +1,139 @@ +import { IMixerProtocol } from '../MixerProtocolInterface' + +export const BehringerXrMaster: IMixerProtocol = { + protocol: 'OSC', + label: 'Behringer XR-series / Midas MR-series', + presetFileExtension: '', + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: true, + pingCommand: [ + { + mixerMessage: '/xremote', + }, + { + mixerMessage: '/meters', + value: '/meters/1', + type: 's', + }, + { + mixerMessage: '/meters', + value: '/meters/6', + type: 's', + }, + ], + pingTime: 9500, + initializeCommands: [ + { + mixerMessage: '/ch/{channel}/mix/fader', + }, + { + mixerMessage: '/ch/{channel}/config/name', + }, + { + mixerMessage: '/ch/{channel}/mix/{argument}/level', + type: 'aux', + }, + { + mixerMessage: '/ch/{channel}/dyn/thr', + }, + { + mixerMessage: '/ch/{channel}/dyn/ratio', + }, + { + mixerMessage: '/ch/{channel}/delay/time', + }, + { + mixerMessage: '/ch/{channel}/eq/1/g', + }, + { + mixerMessage: '/ch/{channel}/eq/2/g', + }, + { + mixerMessage: '/ch/{channel}/eq/3/g', + }, + { + mixerMessage: '/ch/{channel}/eq/4/g', + }, + ], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/ch/{channel}/mix/fader', + }, + ], + CHANNEL_VU: [ + { + mixerMessage: '/meters/1', + }, + ], + CHANNEL_VU_REDUCTION: [ + { + mixerMessage: '/meters/6', + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '/ch/{channel}/config/name', + }, + ], + AUX_LEVEL: [ + { + mixerMessage: '/ch/{channel}/mix/{argument}/level', + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: '/ch/{channel}/mix/on', + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/ch/{channel}/mix/fader', + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '/ch/{channel}/config/name', + }, + ], + AUX_LEVEL: [ + { + mixerMessage: '/ch/{channel}/mix/{argument}/level', + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: '/ch/{channel}/mix/on', + value: 0, + type: 'f', + }, + ], + CHANNEL_MUTE_OFF: [ + { + mixerMessage: '/ch/{channel}/mix/on', + value: 1, + type: 'f', + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/casparCGMaster.ts b/shared/src/constants/mixerProtocols/casparCGMaster.ts new file mode 100644 index 00000000..3a9d7aa8 --- /dev/null +++ b/shared/src/constants/mixerProtocols/casparCGMaster.ts @@ -0,0 +1,186 @@ +import { + ICasparCGMixerGeometry, + ICasparCGMixerGeometryFile, +} from '../MixerProtocolInterface' + +// TODO: This is just template data to avoid error if not loading +// default.caspar.ccg from storage folder +// should be simplified when storage is tested on new installations. +let geometry: ICasparCGMixerGeometryFile = { + label: 'Sofie CasparCG Example', + fromMixer: { + CHANNEL_VU: [ + [ + '/channel/1/stage/layer/51/audio/1/pFS', + '/channel/1/stage/layer/51/audio/2/pFS', + ], + [ + '/channel/1/stage/layer/52/audio/1/pFS', + '/channel/1/stage/layer/52/audio/2/pFS', + ], + [ + '/channel/1/stage/layer/53/audio/1/pFS', + '/channel/1/stage/layer/53/audio/2/pFS', + ], + [ + '/channel/1/stage/layer/54/audio/1/pFS', + '/channel/1/stage/layer/54/audio/2/pFS', + ], + [ + '/channel/1/stage/layer/55/audio/1/pFS', + '/channel/1/stage/layer/55/audio/2/pFS', + ], + [ + '/channel/1/stage/layer/56/audio/1/pFS', + '/channel/1/stage/layer/56/audio/2/pFS', + ], + ], + }, + toMixer: { + PFL_AUX_FADER_LEVEL: [ + [{ channel: 2, layer: 51 }], + [{ channel: 2, layer: 52 }], + [{ channel: 2, layer: 53 }], + [{ channel: 2, layer: 54 }], + [{ channel: 2, layer: 55 }], + [{ channel: 2, layer: 56 }], + ], + NEXT_AUX_FADER_LEVEL: [ + [{ channel: 2, layer: 51 }], + [{ channel: 2, layer: 52 }], + [{ channel: 2, layer: 53 }], + [{ channel: 2, layer: 54 }], + [{ channel: 2, layer: 55 }], + [{ channel: 2, layer: 56 }], + ], + PGM_CHANNEL_FADER_LEVEL: [ + [ + { channel: 1, layer: 51 }, + { channel: 3, layer: 51 }, + ], + [ + { channel: 1, layer: 52 }, + { channel: 3, layer: 52 }, + ], + [ + { channel: 1, layer: 53 }, + { channel: 3, layer: 53 }, + ], + [ + { channel: 1, layer: 54 }, + { channel: 3, layer: 54 }, + ], + [ + { channel: 1, layer: 55 }, + { channel: 3, layer: 55 }, + ], + [ + { channel: 1, layer: 56 }, + { channel: 3, layer: 56 }, + ], + ], + }, + channelLabels: ['RM1', 'RM2', 'RM3', 'RM4', 'RM5', 'MP1'], + sourceOptions: { + sources: [ + { channel: 2, layer: 51, producer: '', file: '' }, + { channel: 2, layer: 52, producer: '', file: '' }, + { channel: 2, layer: 53, producer: '', file: '' }, + { channel: 2, layer: 54, producer: '', file: '' }, + { channel: 2, layer: 55, producer: '', file: '' }, + { channel: 2, layer: 56, producer: '', file: '' }, + ], + options: { + CHANNEL_LAYOUT: { + '1L-2R': '8ch2', + '1L-1R': '4ch-dleft', + '2L-2R': '4ch-dright', + }, + }, + }, +} + +let CasparCGMasterObject: ICasparCGMixerGeometry = { + protocol: 'CasparCG', + label: `CasparCG Audio Mixer`, + presetFileExtension: '', + MAX_UPDATES_PER_SECOND: 10, + studio: 'studio0', + leadingZeros: false, + pingTime: 0, + fromMixer: geometry.fromMixer, + toMixer: geometry.toMixer, + channelLabels: geometry.channelLabels, + sourceOptions: geometry.sourceOptions, + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.001, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, + //CHANNELTYES ARE NOT IMPLEMENTED. + //THIS IS JUST TO AVOID ERRORS AS + //channelTypes are moved to IMixerProtocolGeneric + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: 'MIXER ${CHANNEL} VOLUME ', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_VU: [ + { + mixerMessage: + '/channel/{ch}/stage/layer/{layer}/audio/1/pFS', + }, + { + mixerMessage: + '/channel/{ch}/stage/layer/{layer}/audio/2/pFS', + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: 'none', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_INPUT_SELECTOR: [ + { + mixerMessage: '', + label: '1L-2R', + }, + { + mixerMessage: '', + label: '1L-1R', + }, + { + mixerMessage: '', + label: '2L-2R', + }, + ], + }, + }, + ], +} + +export const CasparCGMaster = CasparCGMasterObject diff --git a/shared/src/constants/mixerProtocols/genericMidi.ts b/shared/src/constants/mixerProtocols/genericMidi.ts new file mode 100644 index 00000000..2c90ddeb --- /dev/null +++ b/shared/src/constants/mixerProtocols/genericMidi.ts @@ -0,0 +1,80 @@ +import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface' + +export const GenericMidi: IMixerProtocol = { + protocol: 'MIDI', + label: 'Generic Midi', + presetFileExtension: '', + loadPresetCommand: [emptyMixerMessage()], + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, + pingCommand: [emptyMixerMessage()], + pingResponseCommand: [emptyMixerMessage()], + pingTime: 0, + initializeCommands: [emptyMixerMessage()], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '0', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], //PgmChange 0 - ignores this command + CHANNEL_VU: [ + { + mixerMessage: '0', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], //PgmChange 0 - ignores this command + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], + CHANNEL_NAME: [emptyMixerMessage()], + PFL: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [emptyMixerMessage()], + CHANNEL_MUTE_OFF: [emptyMixerMessage()], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '38', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_NAME: [emptyMixerMessage()], + PFL_ON: [emptyMixerMessage()], + PFL_OFF: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [emptyMixerMessage()], + CHANNEL_MUTE_OFF: [emptyMixerMessage()], + }, + }, + ], + fader: { + min: 0, + max: 127, + zero: 100, + step: 1, + }, + meter: { + min: 0, + max: 127, + zero: 100, + test: 80, + }, +} diff --git a/shared/src/constants/mixerProtocols/midasMaster.ts b/shared/src/constants/mixerProtocols/midasMaster.ts new file mode 100644 index 00000000..207e52de --- /dev/null +++ b/shared/src/constants/mixerProtocols/midasMaster.ts @@ -0,0 +1,513 @@ +import { IMixerProtocol, fxParamsList } from '../MixerProtocolInterface' + +export const MidasMaster: IMixerProtocol = { + protocol: 'OSC', + fxList: fxParamsList, + label: 'Midas M32 / Behringer X32 Master Mode', + presetFileExtension: 'X32', + loadPresetCommand: [ + { + mixerMessage: '/load', + }, + ], + MAX_UPDATES_PER_SECOND: 15, + leadingZeros: true, + pingCommand: [ + { + mixerMessage: '/xremote', + }, + { + mixerMessage: '/meters', + value: '/meters/1', + type: 's', + }, + ], + pingTime: 9500, + mixerTimeout: 2000, + initializeCommands: [ + { + mixerMessage: '/ch/{channel}/mix/fader', + }, + { + mixerMessage: '/ch/{channel}/config/name', + }, + { + mixerMessage: '/ch/{channel}/mix/{argument}/level', + type: 'aux', + }, + { + mixerMessage: '/ch/{channel}/preamp/trim', + }, + { + mixerMessage: '/ch/{channel}/dyn/thr', + }, + { + mixerMessage: '/ch/{channel}/dyn/ratio', + }, + { + mixerMessage: '/ch/{channel}/delay/time', + }, + { + mixerMessage: '/ch/{channel}/eq/1/g', + }, + { + mixerMessage: '/ch/{channel}/eq/2/g', + }, + { + mixerMessage: '/ch/{channel}/eq/3/g', + }, + { + mixerMessage: '/ch/{channel}/eq/4/g', + }, + { + mixerMessage: '/ch/{channel}/dyn/thr', + }, + { + mixerMessage: '/ch/{channel}/dyn/ratio', + }, + { + mixerMessage: '/ch/{channel}/dyn/attack', + }, + { + mixerMessage: '/ch/{channel}/dyn/hold', + }, + { + mixerMessage: '/ch/{channel}/dyn/knee', + }, + { + mixerMessage: '/ch/{channel}/dyn/mgain', + }, + { + mixerMessage: '/ch/{channel}/dyn/ratio', + }, + { + mixerMessage: '/ch/{channel}/dyn/on', + }, + { + mixerMessage: '/ch/{channel}/delay/time', + }, + { + mixerMessage: '/ch/{channel}/eq/1/g', + }, + { + mixerMessage: '/ch/{channel}/eq/1/f', + }, + { + mixerMessage: '/ch/{channel}/eq/2/f', + }, + { + mixerMessage: '/ch/{channel}/eq/3/f', + }, + { + mixerMessage: '/ch/{channel}/eq/4/f', + }, + { + mixerMessage: '/ch/{channel}/eq/1/q', + }, + { + mixerMessage: '/ch/{channel}/eq/2/q', + }, + { + mixerMessage: '/ch/{channel}/eq/3/q', + }, + { + mixerMessage: '/ch/{channel}/eq/4/q', + }, + ], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/ch/{channel}/mix/fader', + }, + ], + CHANNEL_VU: [ + { + mixerMessage: '/meters/1', + }, + ], + [fxParamsList.GainTrim]: [ + { + mixerMessage: '/ch/{channel}/preamp/trim', + minLabel: -18, + maxLabel: 18, + label: 'Gain Trim', + valueLabel: ' dB', + }, + ], + [fxParamsList.CompOnOff]: [ + { + mixerMessage: '/ch/{channel}/dyn/on', + minLabel: 0, + maxLabel: 1, + label: 'Comp On/Off', + }, + ], + [fxParamsList.CompThrs]: [ + { + mixerMessage: '/ch/{channel}/dyn/thr', + minLabel: -60, + maxLabel: 0, + label: 'Threshold', + valueLabel: ' dB', + }, + ], + [fxParamsList.CompRatio]: [ + { + mixerMessage: '/ch/{channel}/dyn/ratio', + min: 0, + max: 11, + minLabel: 0, + maxLabel: 11, + label: 'Ratio', + valueAsLabels: [ + '1.1', + '1.3', + '1.5', + '2.0', + '2.5', + '3.0', + '4.0', + '5.0', + '7.0', + '10', + '20', + '100', + ], + valueLabel: ' :1', + }, + ], + [fxParamsList.CompAttack]: [ + { + mixerMessage: '/ch/{channel}/dyn/attack', + minLabel: 0, + maxLabel: 120, + label: 'Attack', + valueLabel: ' ms', + }, + ], + [fxParamsList.CompHold]: [ + { + mixerMessage: '/ch/{channel}/dyn/hold', + minLabel: 0, + maxLabel: 2000, + label: 'Hold', + valueLabel: ' ms', + }, + ], + [fxParamsList.CompKnee]: [ + { + mixerMessage: '/ch/{channel}/dyn/knee', + minLabel: 0, + maxLabel: 5, + label: 'Knee', + valueLabel: ' ', + }, + ], + [fxParamsList.CompMakeUp]: [ + { + mixerMessage: '/ch/{channel}/dyn/mgain', + minLabel: 0, + maxLabel: 24, + label: 'MakeUp', + valueLabel: ' dB', + }, + ], + [fxParamsList.CompRelease]: [ + { + mixerMessage: '/ch/{channel}/dyn/release', + minLabel: 5, + maxLabel: 4000, + label: 'Release', + valueLabel: ' ms', + }, + ], + [fxParamsList.DelayTime]: [ + { + mixerMessage: '/ch/{channel}/delay/time', + minLabel: 0, + maxLabel: 500, + label: 'Time', + valueLabel: ' ms', + }, + ], + [fxParamsList.EqGain01]: [ + { + mixerMessage: '/ch/{channel}/eq/1/g', + minLabel: -15, + maxLabel: 15, + label: 'Low', + valueLabel: ' dB', + }, + ], + [fxParamsList.EqGain02]: [ + { + mixerMessage: '/ch/{channel}/eq/2/g', + minLabel: -15, + maxLabel: 15, + label: 'LoMid', + valueLabel: ' dB', + }, + ], + [fxParamsList.EqGain03]: [ + { + mixerMessage: '/ch/{channel}/eq/3/g', + minLabel: -15, + maxLabel: 15, + label: 'HiMid', + valueLabel: ' dB', + }, + ], + [fxParamsList.EqGain04]: [ + { + mixerMessage: '/ch/{channel}/eq/4/g', + minLabel: -15, + maxLabel: 15, + label: 'High', + valueLabel: ' dB', + }, + ], + [fxParamsList.EqFreq01]: [ + { + mixerMessage: '/ch/{channel}/eq/1/f', + minLabel: 20, + maxLabel: 20000, + label: 'Low Freq', + valueLabel: ' Freq', + }, + ], + [fxParamsList.EqFreq02]: [ + { + mixerMessage: '/ch/{channel}/eq/2/f', + minLabel: 20, + maxLabel: 20000, + label: 'LoMid freq', + valueLabel: ' Freq', + }, + ], + [fxParamsList.EqFreq03]: [ + { + mixerMessage: '/ch/{channel}/eq/3/f', + minLabel: 20, + maxLabel: 20000, + label: 'HiMid freq', + valueLabel: ' Freq', + }, + ], + [fxParamsList.EqFreq04]: [ + { + mixerMessage: '/ch/{channel}/eq/4/f', + minLabel: 20, + maxLabel: 20000, + label: 'High freq', + valueLabel: ' Freq', + }, + ], + [fxParamsList.EqQ01]: [ + { + mixerMessage: '/ch/{channel}/eq/1/q', + minLabel: 10, + maxLabel: 0.3, + label: 'Low Q', + valueLabel: ' Q', + }, + ], + [fxParamsList.EqQ02]: [ + { + mixerMessage: '/ch/{channel}/eq/2/q', + minLabel: 10, + maxLabel: 0.3, + label: 'LoMid Q', + valueLabel: ' Q', + }, + ], + [fxParamsList.EqQ03]: [ + { + mixerMessage: '/ch/{channel}/eq/3/q', + minLabel: 10, + maxLabel: 0.3, + label: 'HiMid Q', + valueLabel: ' Q', + }, + ], + [fxParamsList.EqQ04]: [ + { + mixerMessage: '/ch/{channel}/eq/4/q', + minLabel: 10, + maxLabel: 0.3, + label: 'High Q', + valueLabel: ' Q', + }, + ], + AUX_LEVEL: [ + { + mixerMessage: '/ch/{channel}/mix/{argument}/level', + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: '/ch/{channel}/mix/on', + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/ch/{channel}/mix/fader', + }, + ], + [fxParamsList.GainTrim]: [ + { + mixerMessage: '/ch/{channel}/preamp/trim', + minLabel: -18, + maxLabel: 18, + label: 'Gain Trim', + valueLabel: ' dB', + }, + ], + [fxParamsList.CompOnOff]: [ + { + mixerMessage: '/ch/{channel}/dyn/on', + minLabel: 0, + maxLabel: 1, + label: 'Comp On/Off', + }, + ], + [fxParamsList.CompThrs]: [ + { + mixerMessage: '/ch/{channel}/dyn/thr', + }, + ], + [fxParamsList.CompRatio]: [ + { + mixerMessage: '/ch/{channel}/dyn/ratio', + }, + ], + [fxParamsList.CompAttack]: [ + { + mixerMessage: '/ch/{channel}/dyn/attack', + }, + ], + [fxParamsList.CompHold]: [ + { + mixerMessage: '/ch/{channel}/dyn/hold', + }, + ], + [fxParamsList.CompKnee]: [ + { + mixerMessage: '/ch/{channel}/dyn/knee', + }, + ], + [fxParamsList.CompMakeUp]: [ + { + mixerMessage: '/ch/{channel}/dyn/mgain', + }, + ], + [fxParamsList.CompRelease]: [ + { + mixerMessage: '/ch/{channel}/dyn/release', + }, + ], + [fxParamsList.DelayTime]: [ + { + mixerMessage: '/ch/{channel}/delay/time', + }, + ], + [fxParamsList.EqGain01]: [ + { + mixerMessage: '/ch/{channel}/eq/1/g', + }, + ], + [fxParamsList.EqGain02]: [ + { + mixerMessage: '/ch/{channel}/eq/2/g', + }, + ], + [fxParamsList.EqGain03]: [ + { + mixerMessage: '/ch/{channel}/eq/3/g', + }, + ], + [fxParamsList.EqGain04]: [ + { + mixerMessage: '/ch/{channel}/eq/4/g', + }, + ], + [fxParamsList.EqFreq01]: [ + { + mixerMessage: '/ch/{channel}/eq/1/f', + }, + ], + [fxParamsList.EqFreq02]: [ + { + mixerMessage: '/ch/{channel}/eq/2/f', + }, + ], + [fxParamsList.EqFreq03]: [ + { + mixerMessage: '/ch/{channel}/eq/3/f', + }, + ], + [fxParamsList.EqFreq04]: [ + { + mixerMessage: '/ch/{channel}/eq/4/f', + }, + ], + [fxParamsList.EqQ01]: [ + { + mixerMessage: '/ch/{channel}/eq/1/q', + }, + ], + [fxParamsList.EqQ02]: [ + { + mixerMessage: '/ch/{channel}/eq/2/q', + }, + ], + [fxParamsList.EqQ03]: [ + { + mixerMessage: '/ch/{channel}/eq/3/q', + }, + ], + [fxParamsList.EqQ04]: [ + { + mixerMessage: '/ch/{channel}/eq/4/q', + }, + ], + AUX_LEVEL: [ + { + mixerMessage: '/ch/{channel}/mix/{argument}/level', + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: '/ch/{channel}/mix/on', + value: 0, + type: 'f', + }, + ], + CHANNEL_MUTE_OFF: [ + { + mixerMessage: '/ch/{channel}/mix/on', + value: 1, + type: 'f', + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/reaperMaster.ts b/shared/src/constants/mixerProtocols/reaperMaster.ts new file mode 100644 index 00000000..08d9263c --- /dev/null +++ b/shared/src/constants/mixerProtocols/reaperMaster.ts @@ -0,0 +1,148 @@ +import { IMixerProtocol } from '../MixerProtocolInterface' + +export const ReaperMaster: IMixerProtocol = { + protocol: 'OSC', + label: 'Reaper DAW Master mode(reaper.fm)', + presetFileExtension: '', + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, //some OSC protocols needs channels to be 01, 02 etc. + pingTime: 0, //Set to value to get MixerOnline status + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/track/{channel}/volume', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_VU: [ + { + mixerMessage: '/track/{channel}/vu', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '/track/{channel}/name', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/track/{channel}/volume', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_NAME: [ + { + mixerMessage: '/track/{channel}/name', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + PFL_ON: [ + { + mixerMessage: '/track/{channel}/solo', + value: 1, + type: 'i', + min: 0, + max: 1, + zero: 0.75, + }, + ], + PFL_OFF: [ + { + mixerMessage: '/track/{channel}/solo', + value: 0, + type: 'i', + min: 0, + max: 1, + zero: 0.75, + }, + ], + }, + }, + { + channelTypeName: 'MASTER', + channelTypeColor: '#0f0f3f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/master/volume', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_VU: [ + { + mixerMessage: '/master/vu/L', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + { + mixerMessage: '/master/vu/R', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: '/master/volume', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/vMix.ts b/shared/src/constants/mixerProtocols/vMix.ts new file mode 100644 index 00000000..5be3db2a --- /dev/null +++ b/shared/src/constants/mixerProtocols/vMix.ts @@ -0,0 +1,236 @@ +import { IMixerProtocol, fxParamsList } from '../MixerProtocolInterface' + +export const VMix: IMixerProtocol = { + protocol: 'VMIX', + fxList: fxParamsList, + label: 'VMix Audio Control', + presetFileExtension: 'vmix', + loadPresetCommand: [ + { + mixerMessage: '/load', + }, + ], + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: true, + pingCommand: [ + // { + // mixerMessage: '/xremote', + // }, + // { + // mixerMessage: '/meters', + // value: '/meters/1', + // type: 's', + // }, + ], + pingTime: 9500, + initializeCommands: [ + { + mixerMessage: 'SetVolume', + }, + { + mixerMessage: 'AudioAutoOff', + }, + // { + // mixerMessage: '/ch/{channel}/config/name', + // }, + // { + // mixerMessage: '/ch/{channel}/mix/{argument}/level', + // type: 'aux', + // }, + // { + // mixerMessage: '/ch/{channel}/preamp/trim', + // }, + // { + // mixerMessage: '/ch/{channel}/dyn/thr', + // }, + // { + // mixerMessage: '/ch/{channel}/dyn/ratio', + // }, + // { + // mixerMessage: '/ch/{channel}/delay/time', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/1/g', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/2/g', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/3/g', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/4/g', + // }, + // { + // mixerMessage: '/ch/{channel}/dyn/thr', + // }, + // { + // mixerMessage: '/ch/{channel}/dyn/ratio', + // }, + // { + // mixerMessage: '/ch/{channel}/dyn/attack', + // }, + // { + // mixerMessage: '/ch/{channel}/dyn/hold', + // }, + // { + // mixerMessage: '/ch/{channel}/dyn/knee', + // }, + // { + // mixerMessage: '/ch/{channel}/dyn/mgain', + // }, + // { + // mixerMessage: '/ch/{channel}/dyn/ratio', + // }, + // { + // mixerMessage: '/ch/{channel}/delay/time', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/1/g', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/1/f', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/2/f', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/3/f', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/4/f', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/1/q', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/2/q', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/3/q', + // }, + // { + // mixerMessage: '/ch/{channel}/eq/4/q', + // }, + ], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: 'SetVolume', + }, + ], + CHANNEL_VU: [ + { + mixerMessage: '/meters/1', + }, + { + mixerMessage: '/meters/2', + }, + ], + CHANNEL_INPUT_GAIN: [ + { + mixerMessage: 'SetGain', + minLabel: 0, + maxLabel: 24, + label: 'Gain Trim', + valueLabel: ' dB', + }, + ], + AUX_LEVEL: [ + { + mixerMessage: '/ch/{channel}/mix/{argument}/level', + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: '/ch/{channel}/mix/on', + }, + ], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: 'SetVolume', + }, + ], + CHANNEL_INPUT_SELECTOR: [ + { + mixerMessage: 'AudioChannelMatrixApplyPreset', + label: 'LR', + value: 'Default', + }, + { + mixerMessage: 'AudioChannelMatrixApplyPreset', + label: 'LL', + value: 'LL', + }, + { + mixerMessage: 'AudioChannelMatrixApplyPreset', + label: 'RR', + value: 'RR', + }, + ], + CHANNEL_INPUT_GAIN: [ + { + mixerMessage: 'SetGain', + minLabel: 0, + maxLabel: 24, + label: 'Gain Trim', + valueLabel: ' dB', + min: 0, + max: 24, + }, + ], + CHANNEL_MUTE_ON: [ + { + mixerMessage: 'AudioOff', + value: 0, + type: 'f', + }, + ], + CHANNEL_MUTE_OFF: [ + { + mixerMessage: 'AudioOn', + value: 1, + type: 'f', + }, + ], + PFL_OFF: [ + { + mixerMessage: 'SoloOff', + value: 1, + type: 'f', + }, + ], + PFL_ON: [ + { + mixerMessage: 'SoloOn', + value: 1, + type: 'f', + }, + ], + AUX_LEVEL: [ + { + mixerMessage: '/ch/{channel}/mix/{argument}/level', + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/mixerProtocols/yamahaQLCL.ts b/shared/src/constants/mixerProtocols/yamahaQLCL.ts new file mode 100644 index 00000000..8d122a17 --- /dev/null +++ b/shared/src/constants/mixerProtocols/yamahaQLCL.ts @@ -0,0 +1,122 @@ +import { IMixerProtocol, emptyMixerMessage } from '../MixerProtocolInterface' + +export const YamahaQLCL: IMixerProtocol = { + protocol: 'QLCL', + label: 'Yamaha QL/CL', + presetFileExtension: '', + loadPresetCommand: [emptyMixerMessage()], + MAX_UPDATES_PER_SECOND: 10, + leadingZeros: false, + pingCommand: [emptyMixerMessage()], + pingResponseCommand: [emptyMixerMessage()], + pingTime: 10000, + initializeCommands: [ + { + mixerMessage: 'f0 43 30 3e 19 01 00 37 00 00 {channel} f7', + value: 0, + type: '', + min: 0, + max: 1, + zero: 0.75, + }, + ], + channelTypes: [ + { + channelTypeName: 'CH', + channelTypeColor: '#2f2f2f', + fromMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'f0 43 10 3e 19 01 00 37 00 00 {channel} 00 00 00 {level} f7', + value: 0, + type: '', + min: 0, + max: 1, + zero: 0.75, + }, + ], //PgmChange 0 - ignores this command + CHANNEL_VU: [ + { + mixerMessage: '0', + value: 0, + type: 'f', + min: 0, + max: 1, + zero: 0.75, + }, + ], //PgmChange 0 - ignores this command + CHANNEL_VU_REDUCTION: [emptyMixerMessage()], + CHANNEL_NAME: [emptyMixerMessage()], + PFL: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [ + { + mixerMessage: + 'f0 43 10 3e 19 01 00 35 00 00 {channel} 00 00 00 00 00 f7', + value: 0, + type: '', + min: 0, + max: 1, + zero: 0.75, + }, + ], + // Only MUTE_ON is used as receiver + CHANNEL_MUTE_OFF: [emptyMixerMessage()], + }, + toMixer: { + CHANNEL_OUT_GAIN: [ + { + mixerMessage: + 'f0 43 10 3e 19 01 00 37 00 00 {channel} 00 00 00 {level} f7', + value: 0, + type: '', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_NAME: [emptyMixerMessage()], + PFL_ON: [emptyMixerMessage()], + PFL_OFF: [emptyMixerMessage()], + NEXT_SEND: [emptyMixerMessage()], + AUX_LEVEL: [emptyMixerMessage()], + CHANNEL_MUTE_ON: [ + { + mixerMessage: + 'f0 43 10 3e 19 01 00 35 00 00 {channel} 00 00 00 00 00 f7', + value: 0, + type: '', + min: 0, + max: 1, + zero: 0.75, + }, + ], + CHANNEL_MUTE_OFF: [ + { + mixerMessage: + 'f0 43 10 3e 19 01 00 35 00 00 {channel} 00 00 00 00 01 f7', + value: 0, + type: '', + min: 0, + max: 1, + zero: 0.75, + }, + ], + }, + }, + ], + fader: { + min: 0, + max: 1, + zero: 0.75, + step: 0.01, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, +} diff --git a/shared/src/constants/remoteProtocols/HuiRemoteFaderPresets.ts b/shared/src/constants/remoteProtocols/HuiRemoteFaderPresets.ts new file mode 100644 index 00000000..01c83e2e --- /dev/null +++ b/shared/src/constants/remoteProtocols/HuiRemoteFaderPresets.ts @@ -0,0 +1,164 @@ +export interface IMidiSendMessage { + message: string + value: any + type: MidiSendTypes +} + +export enum MidiSendTypes { + disabled, + playNote, + stopNote, + sendControlChange, + sendPitchBend, +} + +export interface IMidiReceiveMessage { + message: string + value: any + type: MidiReceiveTypes +} +export enum MidiReceiveTypes { + disabled, + noteon, + noteoff, + controlchange, + pitchbend, +} + +export interface IRemoteProtocol { + protocol: string + label: string + mode: string + leadingZeros: boolean + initializeCommands: [IMidiSendMessage] + fromRemote: { + CHANNEL_PGM_ON_OFF: IMidiReceiveMessage + CHANNEL_PST_ON_OFF: IMidiReceiveMessage + CHANNEL_PFL_ON_OFF: IMidiReceiveMessage + CHANNEL_FADER_LEVEL: IMidiReceiveMessage + X_MIX: IMidiReceiveMessage + FADE_TO_BLACK: IMidiReceiveMessage + SNAP_RECALL: IMidiReceiveMessage + } + toRemote: { + STATE_CHANNEL_PGM: IMidiSendMessage + STATE_CHANNEL_PST: IMidiSendMessage + STATE_CHANNEL_PFL: IMidiSendMessage + STATE_CHANNEL_FADER_LEVEL: Array + } + fader: { + min: number + max: number + zero: number + step: number + } + meter: { + min: number + max: number + zero: number + test: number + } +} + +export const RemoteFaderPresets: { [key: string]: IRemoteProtocol } = { + hui: { + protocol: 'MIDI', + label: 'Generic HUI Midicontroller', + mode: 'client', + leadingZeros: true, + initializeCommands: [ + { + message: '', + value: '', + type: MidiSendTypes.disabled, + }, + ], + fromRemote: { + CHANNEL_PGM_ON_OFF: { + message: '', + value: '', + type: MidiReceiveTypes.disabled, + }, + CHANNEL_PST_ON_OFF: { + message: '', + value: '', + type: MidiReceiveTypes.disabled, + }, + CHANNEL_PFL_ON_OFF: { + message: '', + value: '', + type: MidiReceiveTypes.disabled, + }, + CHANNEL_FADER_LEVEL: { + message: '0', + value: '', + type: MidiReceiveTypes.controlchange, + }, + X_MIX: { + message: '', + value: '', + type: MidiReceiveTypes.disabled, + }, + FADE_TO_BLACK: { + message: '', + value: '', + type: MidiReceiveTypes.disabled, + }, + SNAP_RECALL: { + message: '', + value: '', + type: MidiReceiveTypes.disabled, + }, + }, + toRemote: { + STATE_CHANNEL_PGM: { + message: '', + value: '', + type: MidiSendTypes.disabled, + }, + STATE_CHANNEL_PST: { + message: '', + value: '', + type: MidiSendTypes.disabled, + }, + STATE_CHANNEL_PFL: { + message: '', + value: '', + type: MidiSendTypes.disabled, + }, + STATE_CHANNEL_FADER_LEVEL: [ + { + message: '21', + value: '', + type: MidiSendTypes.sendControlChange, + }, + { + message: '01', + value: '', + type: MidiSendTypes.sendControlChange, + }, + ], + }, + fader: { + min: 0, + max: 127, + zero: 70, + step: 1, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, + }, +} + +export const RemoteFaderProtocolList = Object.getOwnPropertyNames( + RemoteFaderPresets +).map((preset) => { + return { + value: preset, + label: RemoteFaderPresets[preset].label, + } +}) diff --git a/shared/src/constants/remoteProtocols/SkaarhojProtocol.ts b/shared/src/constants/remoteProtocols/SkaarhojProtocol.ts new file mode 100644 index 00000000..275c38db --- /dev/null +++ b/shared/src/constants/remoteProtocols/SkaarhojProtocol.ts @@ -0,0 +1,164 @@ +export interface IRawSendMessage { + message: string + value: any + type: RawSendTypes +} + +export enum RawSendTypes { + disabled, + playNote, + stopNote, + sendControlChange, + sendPitchBend, +} + +export interface IRawReceiveMessage { + message: string + value: any + type: RawReceiveTypes +} +export enum RawReceiveTypes { + disabled, + noteon, + noteoff, + controlchange, + pitchbend, +} + +export interface IRemoteProtocol { + protocol: string + label: string + mode: string + leadingZeros: boolean + initializeCommands: [IRawSendMessage] + fromRemote: { + CHANNEL_PGM_ON_OFF: IRawReceiveMessage + CHANNEL_PST_ON_OFF: IRawReceiveMessage + CHANNEL_PFL_ON_OFF: IRawReceiveMessage + CHANNEL_FADER_LEVEL: IRawReceiveMessage + X_MIX: IRawReceiveMessage + FADE_TO_BLACK: IRawReceiveMessage + SNAP_RECALL: IRawReceiveMessage + } + toRemote: { + STATE_CHANNEL_PGM: IRawSendMessage + STATE_CHANNEL_PST: IRawSendMessage + STATE_CHANNEL_PFL: IRawSendMessage + STATE_CHANNEL_FADER_LEVEL: Array + } + fader: { + min: number + max: number + zero: number + step: number + } + meter: { + min: number + max: number + zero: number + test: number + } +} + +export const RemoteFaderPresets: { [key: string]: IRemoteProtocol } = { + rawPanel: { + protocol: 'RAW', + label: 'Generic Skaarhoj Protocol', + mode: 'client', + leadingZeros: false, + initializeCommands: [ + { + message: '', + value: '', + type: RawSendTypes.disabled, + }, + ], + fromRemote: { + CHANNEL_PGM_ON_OFF: { + message: '', + value: '', + type: RawReceiveTypes.disabled, + }, + CHANNEL_PST_ON_OFF: { + message: '', + value: '', + type: RawReceiveTypes.disabled, + }, + CHANNEL_PFL_ON_OFF: { + message: '', + value: '', + type: RawReceiveTypes.disabled, + }, + CHANNEL_FADER_LEVEL: { + message: '0', + value: '', + type: RawReceiveTypes.controlchange, + }, + X_MIX: { + message: '', + value: '', + type: RawReceiveTypes.disabled, + }, + FADE_TO_BLACK: { + message: '', + value: '', + type: RawReceiveTypes.disabled, + }, + SNAP_RECALL: { + message: '', + value: '', + type: RawReceiveTypes.disabled, + }, + }, + toRemote: { + STATE_CHANNEL_PGM: { + message: '', + value: '', + type: RawSendTypes.disabled, + }, + STATE_CHANNEL_PST: { + message: '', + value: '', + type: RawSendTypes.disabled, + }, + STATE_CHANNEL_PFL: { + message: '', + value: '', + type: RawSendTypes.disabled, + }, + STATE_CHANNEL_FADER_LEVEL: [ + { + message: '21', + value: '', + type: RawSendTypes.sendControlChange, + }, + { + message: '01', + value: '', + type: RawSendTypes.sendControlChange, + }, + ], + }, + fader: { + min: 0, + max: 127, + zero: 70, + step: 1, + }, + meter: { + min: 0, + max: 1, + zero: 0.75, + test: 0.6, + }, + }, +} + +export const RemoteFaderProtocolList = Object.getOwnPropertyNames( + RemoteFaderPresets +).map((preset) => { + return { + value: preset, + label: RemoteFaderPresets[preset].label, + } +}) diff --git a/shared/src/reducers/channelsReducer.ts b/shared/src/reducers/channelsReducer.ts new file mode 100644 index 00000000..60984bb3 --- /dev/null +++ b/shared/src/reducers/channelsReducer.ts @@ -0,0 +1,177 @@ +import { + SET_OUTPUT_LEVEL, + SET_ASSIGNED_FADER, + SET_COMPLETE_CH_STATE, + SET_PRIVATE, + FADE_ACTIVE, + SET_AUX_LEVEL, + SET_SINGLE_CH_STATE, + SET_CHANNEL_LABEL, + FLUSH_CHANNEL_LABELS, +} from '../actions/channelActions' + +export interface IChannels { + chMixerConnection: IchMixerConnection[] + } + + export interface IchMixerConnection { + channel: Array + } + + export interface IChannel { + channelType: number + channelTypeIndex: number + assignedFader: number + label?: string + fadeActive: boolean + outputLevel: number + auxLevel: number[] + private?: { + [key: string]: string + } + } + + export interface InumberOfChannels { + numberOfTypeInCh: number[] + } + +const defaultChannelsReducerState = ( + numberOfChannels: InumberOfChannels[] +): IChannels[] => { + let defaultObj: IChannels[] = [ + { + chMixerConnection: [], + }, + ] + + for ( + let mixerIndex = 0; + mixerIndex < numberOfChannels.length; + mixerIndex++ + ) { + let totalNumberOfChannels = 0 + defaultObj[0].chMixerConnection.push({ channel: [] }) + numberOfChannels[mixerIndex].numberOfTypeInCh.forEach( + (channelTypeSize: any, typeIndex: number) => { + for (let index = 0; index < channelTypeSize; index++) { + defaultObj[0].chMixerConnection[mixerIndex].channel[ + totalNumberOfChannels + ] = { + channelType: typeIndex, + channelTypeIndex: index, + assignedFader: totalNumberOfChannels, + fadeActive: false, + outputLevel: 0.0, + auxLevel: [], + } + totalNumberOfChannels++ + } + } + ) + } + + return defaultObj +} + +export const channels = ( + state = defaultChannelsReducerState([{ numberOfTypeInCh: [1] }]), + action: any +): Array => { + let nextState = [ + { + chMixerConnection: [...state[0].chMixerConnection], + }, + ] + + switch (action.type) { + case SET_OUTPUT_LEVEL: + nextState[0].chMixerConnection[action.mixerIndex].channel[ + action.channel + ].outputLevel = parseFloat(action.level) + return nextState + case SET_COMPLETE_CH_STATE: + nextState = defaultChannelsReducerState(action.numberOfTypeChannels) + + nextState[0].chMixerConnection.forEach( + (chMixerConnection: IchMixerConnection, mixerIndex: number) => { + chMixerConnection.channel.forEach( + (channel: any, index: number) => { + if ( + index < + action.allState.chMixerConnection[mixerIndex] + ?.channel.length + ) { + nextState[0].chMixerConnection[ + mixerIndex + ].channel[index] = + action.allState.chMixerConnection[ + mixerIndex + ].channel[index] + } + } + ) + } + ) + + return nextState + case SET_SINGLE_CH_STATE: + nextState[0].chMixerConnection[0].channel[action.channelIndex] = + action.state + return nextState + case FADE_ACTIVE: + nextState[0].chMixerConnection[action.mixerIndex].channel[ + action.channel + ].fadeActive = !!action.active + return nextState + case SET_ASSIGNED_FADER: + nextState[0].chMixerConnection[action.mixerIndex].channel[ + action.channel + ].assignedFader = action.faderNumber + return nextState + case SET_AUX_LEVEL: + let auxLevels = + nextState[0].chMixerConnection[action.mixerIndex].channel[ + action.channel + ].auxLevel + if (action.auxIndex >= auxLevels.length) { + for (let i = 0; i < action.auxIndex; i++) { + if (auxLevels[i] === null) { + auxLevels[action.auxIndex] = -1 + } + } + } + auxLevels[action.auxIndex] = parseFloat(action.level) + nextState[0].chMixerConnection[action.mixerIndex].channel[ + action.channel + ].auxLevel = auxLevels + return nextState + case SET_PRIVATE: + if ( + !nextState[0].chMixerConnection[action.mixerIndex].channel[ + action.channel + ].private + ) { + nextState[0].chMixerConnection[action.mixerIndex].channel[ + action.channel + ].private = {} + } + nextState[0].chMixerConnection[action.mixerIndex].channel[ + action.channel + ].private![action.tag] = action.value + return nextState + case SET_CHANNEL_LABEL: + nextState[0].chMixerConnection[action.mixerIndex].channel[ + action.channel + ].label = action.label + return nextState + case FLUSH_CHANNEL_LABELS: + for (const mixer of nextState[0].chMixerConnection) { + for (const ch of mixer.channel) { + ch.label = undefined + } + } + return nextState + default: + return nextState + } +} diff --git a/shared/src/reducers/fadersReducer.ts b/shared/src/reducers/fadersReducer.ts new file mode 100644 index 00000000..65fb3efa --- /dev/null +++ b/shared/src/reducers/fadersReducer.ts @@ -0,0 +1,363 @@ +import * as FADER_ACTIONS from '../actions/faderActions' +export interface IFaders { + fader: Array + vuMeters: Array +} + +export interface IChannelReference { + mixerIndex: number + channelIndex: number +} + +export interface IFader { + faderLevel: number + inputGain: number + inputSelector: number + label: string + userLabel?: string + pgmOn: boolean + voOn: boolean + slowFadeOn: boolean + pstOn: boolean + pstVoOn: boolean + pflOn: boolean + muteOn: boolean + amixOn: boolean + [fxparam: number]: Array + monitor: number + showChannel: boolean + showInMiniMonitor: boolean + ignoreAutomation: boolean + disabled: boolean + assignedChannels?: IChannelReference[] + + /** + * Assuming that the protocol has a "feature", can it be enabled on this fader? + * If the capibilities object does not exist, yes is assumed. + */ + capabilities?: { + hasAMix?: boolean + hasInputSelector?: boolean + } +} + +export interface IVuMeters { + reductionVal: number +} + +export const defaultFadersReducerState = ( + numberOfFaders: number +): IFaders[] => { + let defaultObj: Array = [ + { + fader: [], + vuMeters: [], + }, + ] + + for (let index = 0; index < numberOfFaders; index++) { + defaultObj[0].fader[index] = { + faderLevel: 0.75, + inputGain: 0.75, + inputSelector: 1, + label: '', + pgmOn: false, + voOn: false, + slowFadeOn: false, + pstOn: false, + pstVoOn: false, + pflOn: false, + muteOn: false, + amixOn: false, + monitor: index + 1, // route fader - aux 1:1 as default + showChannel: true, + showInMiniMonitor: false, + ignoreAutomation: false, + disabled: false, + } + defaultObj[0].vuMeters.push({ + reductionVal: 0.0, + }) + } + return defaultObj +} + +export const faders = ( + state = defaultFadersReducerState(0), + action: any +): Array => { + let nextState = [ + { + vuMeters: [...state[0].vuMeters], + fader: [...state[0].fader], + }, + ] + if ( + action.faderIndex && + (action.faderIndex < 0 || + action.faderIndex >= nextState[0].fader.length) + ) { + return nextState + } + + switch (action.type) { + case FADER_ACTIONS.SET_VU_REDUCTION_LEVEL: + if ( + typeof nextState[0].vuMeters[action.faderIndex] !== 'undefined' + ) { + nextState[0].vuMeters[ + action.faderIndex + ].reductionVal = parseFloat(action.level) + } + return nextState + case FADER_ACTIONS.SET_COMPLETE_FADER_STATE: + nextState = defaultFadersReducerState(action.numberOfTypeChannels) + action.allState.fader.forEach((fader: any, index: number) => { + if (index < nextState[0].fader.length) { + nextState[0].fader[index] = fader + } + }) + return nextState + case FADER_ACTIONS.SET_SINGLE_FADER_STATE: + nextState[0].fader[action.faderIndex] = action.state + return nextState + case FADER_ACTIONS.SET_FADER_LEVEL: + nextState[0].fader[action.faderIndex].faderLevel = parseFloat( + action.level + ) + return nextState + case FADER_ACTIONS.SET_INPUT_GAIN: + nextState[0].fader[action.faderIndex].inputGain = parseFloat( + action.level + ) + return nextState + case FADER_ACTIONS.SET_INPUT_SELECTOR: + nextState[0].fader[action.faderIndex].inputSelector = parseFloat( + action.selected + ) + return nextState + case FADER_ACTIONS.SET_FADER_FX: + if (!nextState[0].fader[action.faderIndex][action.fxParam]) { + nextState[0].fader[action.faderIndex][action.fxParam] = [] + } + nextState[0].fader[action.faderIndex][ + action.fxParam + ][0] = parseFloat(action.level ?? 0) + return nextState + case FADER_ACTIONS.SET_FADER_MONITOR: + nextState[0].fader[action.faderIndex].monitor = action.auxIndex + return nextState + case FADER_ACTIONS.SET_FADER_LABEL: + if (!nextState[0].fader[action.faderIndex]) return nextState + nextState[0].fader[action.faderIndex].label = action.label + return nextState + case FADER_ACTIONS.TOGGLE_PGM: + nextState[0].fader[action.faderIndex].pgmOn = !nextState[0].fader[ + action.faderIndex + ].pgmOn + nextState[0].fader[action.faderIndex].voOn = false + return nextState + case FADER_ACTIONS.SET_PGM: + nextState[0].fader[action.faderIndex].pgmOn = !!action.pgmOn + nextState[0].fader[action.faderIndex].voOn = false + return nextState + case FADER_ACTIONS.TOGGLE_VO: + nextState[0].fader[action.faderIndex].voOn = !nextState[0].fader[ + action.faderIndex + ].voOn + nextState[0].fader[action.faderIndex].pgmOn = false + return nextState + case FADER_ACTIONS.SET_VO: + nextState[0].fader[action.faderIndex].voOn = !!action.voOn + nextState[0].fader[action.faderIndex].pgmOn = false + return nextState + case FADER_ACTIONS.TOGGLE_SLOW_FADE: + nextState[0].fader[action.faderIndex].slowFadeOn = !nextState[0] + .fader[action.faderIndex].slowFadeOn + return nextState + case FADER_ACTIONS.TOGGLE_PST: + if (nextState[0].fader[action.faderIndex].pstOn) { + nextState[0].fader[action.faderIndex].pstOn = false + // Disable toggle to pstVoOn, to enable change pstVoOn: true here: + nextState[0].fader[action.faderIndex].pstVoOn = false + } else if (nextState[0].fader[action.faderIndex].pstVoOn) { + nextState[0].fader[action.faderIndex].pstOn = false + nextState[0].fader[action.faderIndex].pstVoOn = false + } else { + nextState[0].fader[action.faderIndex].pstOn = true + nextState[0].fader[action.faderIndex].pstVoOn = false + } + return nextState + case FADER_ACTIONS.SET_PST: + nextState[0].fader[action.faderIndex].pstOn = !!action.pstOn + nextState[0].fader[action.faderIndex].pstVoOn = false + return nextState + case FADER_ACTIONS.SET_PST_VO: + nextState[0].fader[action.faderIndex].pstVoOn = !!action.pstVoOn + nextState[0].fader[action.faderIndex].pstOn = false + return nextState + case FADER_ACTIONS.TOGGLE_PFL: + nextState[0].fader[action.faderIndex].pflOn = !nextState[0].fader[ + action.faderIndex + ].pflOn + return nextState + case FADER_ACTIONS.SET_PFL: + nextState[0].fader[action.faderIndex].pflOn = !!action.pflOn + return nextState + case FADER_ACTIONS.TOGGLE_MUTE: + nextState[0].fader[action.faderIndex].muteOn = !nextState[0].fader[ + action.faderIndex + ].muteOn + return nextState + case FADER_ACTIONS.SET_MUTE: + nextState[0].fader[action.faderIndex].muteOn = !!action.muteOn + return nextState + case FADER_ACTIONS.SHOW_CHANNEL: + nextState[0].fader[ + action.faderIndex + ].showChannel = !!action.showChannel + return nextState + case FADER_ACTIONS.SHOW_IN_MINI_MONITOR: //faderIndexz // showInMiniMonitor + nextState[0].fader[ + action.faderIndex + ].showInMiniMonitor = !!action.showInMiniMonitor + return nextState + case FADER_ACTIONS.IGNORE_AUTOMATION: //channel // ignoreAutomation + nextState[0].fader[ + action.faderIndex + ].ignoreAutomation = !nextState[0].fader[action.faderIndex] + .ignoreAutomation + return nextState + case FADER_ACTIONS.X_MIX: //none + nextState[0].fader.forEach((item, index) => { + if (!state[0].fader[index].ignoreAutomation) { + let nextPgmOn = state[0].fader[index].pstOn + let nextVoOn = state[0].fader[index].pstVoOn + nextState[0].fader[index].pstOn = + state[0].fader[index].pgmOn + nextState[0].fader[index].pstVoOn = + state[0].fader[index].voOn + nextState[0].fader[index].pgmOn = nextPgmOn + nextState[0].fader[index].voOn = nextVoOn + } + }) + return nextState + case FADER_ACTIONS.NEXT_MIX: //none + nextState[0].fader.forEach((item, index) => { + nextState[0].fader[index].pgmOn = state[0].fader[index].pstOn + nextState[0].fader[index].voOn = state[0].fader[index].pstVoOn + nextState[0].fader[index].pstOn = false + nextState[0].fader[index].pstVoOn = false + }) + return nextState + case FADER_ACTIONS.FADE_TO_BLACK: //none + nextState[0].fader.forEach((item, index) => { + nextState[0].fader[index].pgmOn = false + nextState[0].fader[index].voOn = false + }) + return nextState + case FADER_ACTIONS.CLEAR_PST: //none + nextState[0].fader.forEach((item, index) => { + nextState[0].fader[index].pstOn = false + nextState[0].fader[index].pstVoOn = false + }) + return nextState + case FADER_ACTIONS.SET_CHANNEL_DISABLED: + if (!nextState[0].fader[action.faderIndex]) return nextState + nextState[0].fader[action.faderIndex].disabled = action.disabled + return nextState + case FADER_ACTIONS.TOGGLE_AMIX: //channel + nextState[0].fader[action.faderIndex].amixOn = !nextState[0].fader[ + action.faderIndex + ].amixOn + return nextState + case FADER_ACTIONS.SET_AMIX: //channel + nextState[0].fader[action.faderIndex].amixOn = action.state + return nextState + case FADER_ACTIONS.REMOVE_ALL_ASSIGNED_CHANNELS: //channel + nextState[0].fader.forEach((fader) => { + fader.assignedChannels = [] + }) + return nextState + case FADER_ACTIONS.SET_ASSIGNED_CHANNEL: + let newAssignments: IChannelReference[] = + nextState[0].fader[action.faderIndex].assignedChannels || [] + + if (action.assigned) { + if ( + !newAssignments.includes({ + mixerIndex: action.mixerIndex, + channelIndex: action.channelIndex, + }) + ) { + newAssignments.push({ + mixerIndex: action.mixerIndex, + channelIndex: action.channelIndex, + }) + newAssignments.sort( + (n1: IChannelReference, n2: IChannelReference) => + n1.channelIndex - n2.channelIndex + ) + newAssignments.sort( + (n1: IChannelReference, n2: IChannelReference) => + n1.mixerIndex - n2.mixerIndex + ) + } + } else { + newAssignments = newAssignments.filter((channel) => { + return ( + channel.channelIndex !== action.channelIndex && + channel.mixerIndex !== action.mixerIndex + ) + }) + } + + nextState[0].fader[action.faderIndex].assignedChannels = + newAssignments + return nextState + case FADER_ACTIONS.SET_CAPABILITY: + nextState[0].fader[action.faderIndex].capabilities = { + ...nextState[0].fader[action.faderIndex].capabilities, + [action.capability]: action.enabled, + } + // remove object if empty: + if ( + Object.entries( + nextState[0].fader[action.faderIndex].capabilities! + ).length === 0 + ) { + delete nextState[0].fader[action.faderIndex].capabilities + } + return nextState + case FADER_ACTIONS.TOGGLE_ALL_MANUAL: + const isAllManual = + nextState[0].fader.find((f) => f.ignoreAutomation !== true) === + undefined + + if (isAllManual) { + nextState[0].fader.forEach((f) => { + f.ignoreAutomation = false + }) + } else { + nextState[0].fader.forEach((f) => { + f.ignoreAutomation = true + }) + } + return nextState + case FADER_ACTIONS.UPDATE_LABEL_LIST: + Object.entries(action.update).forEach( + ([index, label]: [string, string]) => { + nextState[0].fader[Number(index)].userLabel = + label === '' ? undefined : label + } + ) + return nextState + case FADER_ACTIONS.FLUSH_FADER_LABELS: + for (const fader of nextState[0].fader) { + fader.label = undefined + } + return nextState + default: + return nextState + } +} diff --git a/shared/src/reducers/indexReducer.ts b/shared/src/reducers/indexReducer.ts new file mode 100644 index 00000000..6e0bac3e --- /dev/null +++ b/shared/src/reducers/indexReducer.ts @@ -0,0 +1,12 @@ +import { combineReducers } from 'redux' +import { channels } from './channelsReducer' +import { settings } from './settingsReducer' +import { faders } from './fadersReducer' + +const indexReducer = combineReducers({ + faders, + channels, + settings, +}) + +export default indexReducer diff --git a/shared/src/reducers/settingsReducer.ts b/shared/src/reducers/settingsReducer.ts new file mode 100644 index 00000000..d8458cdb --- /dev/null +++ b/shared/src/reducers/settingsReducer.ts @@ -0,0 +1,225 @@ +import { MixerProtocolPresets } from '../constants/MixerProtocolPresets' +import { + TOGGLE_SHOW_CHAN_STRIP, + TOGGLE_SHOW_OPTION, + TOGGLE_SHOW_SETTINGS, + TOGGLE_SHOW_STORAGE, + UPDATE_SETTINGS, + SET_MIXER_ONLINE, + TOGGLE_SHOW_MONITOR_OPTIONS, + SET_SERVER_ONLINE, + SET_PAGE, + TOGGLE_SHOW_PAGES_SETUP, + SET_PAGES_LIST, + TOGGLE_SHOW_CHAN_STRIP_FULL, + TOGGLE_SHOW_LABEL_SETTINGS, +} from '../actions/settingsActions' + +export enum PageType { + All, + CustomPage, + } + + export interface ISettings { + /* Sisyfos Settings Version: */ + sisyfosVersion?: string + + /** UI state (non persistant) */ + showSettings: boolean + showPagesSetup: boolean + showLabelSettings: boolean + showChanStrip: number + showChanStripFull: number + showOptions: number | false + showMonitorOptions: number + showStorage: boolean + currentPage: { + type: PageType + start?: number + id?: string + } + customPages: Array + + /** User config */ + numberOfMixers: number + mixers: IMixerSettings[] + enableRemoteFader: boolean + remoteFaderMidiInputPort: string + remoteFaderMidiOutputPort: string + numberOfFaders: number + fadeTime: number // Default fade time for PGM ON - OFF + voFadeTime: number // Default fade time for VO ON - OFF + voLevel: number // Relative level of PGM in % + autoResetLevel: number // Autoreset before pgm on, if level is lower than in % + automationMode: boolean + offtubeMode: boolean + showPfl: boolean + enablePages: boolean + numberOfCustomPages: number + chanStripFollowsPFL: boolean + labelType: 'automatic' | 'user' | 'automation' | 'channel' + + /** Connection state */ + serverOnline: boolean + } + + export interface ICustomPages { + id: string + label: string + faders: Array + } + + export interface IMixerSettings { + mixerProtocol: string + deviceIp: string + devicePort: number + protocolLatency: number // If a protocol has latency and feedback, the amount of time before enabling receiving data from channel again + mixerMidiInputPort: string + mixerMidiOutputPort: string + numberOfChannelsInType: Array + numberOfAux: number + nextSendAux: number + mixerOnline: boolean + localIp: string + localOscPort: number + } + +const defaultSettingsReducerState: Array = [ + { + showSettings: false, + showPagesSetup: false, + showLabelSettings: false, + showChanStrip: -1, + showChanStripFull: -1, + showOptions: false, + showMonitorOptions: -1, + showStorage: false, + currentPage: { type: PageType.All }, + numberOfMixers: 1, + customPages: [], + mixers: [ + { + mixerProtocol: 'sslSystemT', + deviceIp: '0.0.0.0', + devicePort: 10024, + protocolLatency: 220, + mixerMidiInputPort: '', + mixerMidiOutputPort: '', + numberOfAux: 0, + nextSendAux: -1, + numberOfChannelsInType: [8], + mixerOnline: false, + localIp: '0.0.0.0', + localOscPort: 1234, + }, + ], + enableRemoteFader: false, + remoteFaderMidiInputPort: '', + remoteFaderMidiOutputPort: '', + numberOfFaders: 8, + voLevel: 30, + autoResetLevel: 5, + automationMode: true, + offtubeMode: false, + fadeTime: 120, + voFadeTime: 280, + showPfl: false, + enablePages: true, + numberOfCustomPages: 4, + chanStripFollowsPFL: true, + serverOnline: true, + labelType: 'automatic', + }, +] + +export const settings = ( + state = defaultSettingsReducerState, + action: any +): Array => { + let nextState = [Object.assign({}, state[0])] + + switch (action.type) { + case TOGGLE_SHOW_SETTINGS: + nextState[0].showSettings = !nextState[0].showSettings + return nextState + case TOGGLE_SHOW_PAGES_SETUP: + nextState[0].showPagesSetup = !nextState[0].showPagesSetup + return nextState + case TOGGLE_SHOW_LABEL_SETTINGS: + nextState[0].showLabelSettings = !nextState[0].showLabelSettings + return nextState + case TOGGLE_SHOW_CHAN_STRIP: + if (nextState[0].showChanStrip !== action.channel) { + nextState[0].showChanStrip = action.channel + } else { + nextState[0].showChanStrip = -1 + } + return nextState + case TOGGLE_SHOW_CHAN_STRIP_FULL: + if (nextState[0].showChanStripFull !== action.channel) { + nextState[0].showChanStripFull = action.channel + } else { + nextState[0].showChanStripFull = -1 + } + return nextState + case TOGGLE_SHOW_MONITOR_OPTIONS: + if (nextState[0].showMonitorOptions !== action.channel) { + nextState[0].showMonitorOptions = action.channel + } else { + nextState[0].showMonitorOptions = -1 + } + return nextState + case TOGGLE_SHOW_OPTION: + nextState[0].showOptions = + typeof nextState[0].showOptions === 'number' + ? false + : action.channel + return nextState + case TOGGLE_SHOW_STORAGE: + nextState[0].showStorage = !nextState[0].showStorage + return nextState + case SET_PAGE: + nextState[0].currentPage = { + type: action.pageType, + id: action.id, + start: action.start, + } + return nextState + case SET_PAGES_LIST: + nextState[0].customPages = action.customPages + return nextState + case SET_MIXER_ONLINE: + nextState[0].mixers[action.mixerIndex || 0].mixerOnline = + action.mixerOnline + return nextState + case SET_SERVER_ONLINE: + nextState[0].serverOnline = action.serverOnline + return nextState + case UPDATE_SETTINGS: + nextState[0] = action.settings + + // ignore UI state: + nextState[0].showSettings = state[0].showSettings || false + nextState[0].showOptions = state[0].showOptions || false + nextState[0].showMonitorOptions = state[0].showMonitorOptions || -1 + nextState[0].showStorage = state[0].showStorage || false + nextState[0].showChanStrip = state[0].showChanStrip || -1 + nextState[0].serverOnline = state[0].serverOnline || true + nextState[0].currentPage = state[0].currentPage + nextState[0].customPages = state[0].customPages + + if (!nextState[0].mixers) { + nextState = [Object.assign({}, defaultSettingsReducerState[0])] + } + if ( + typeof MixerProtocolPresets[ + nextState[0].mixers[0].mixerProtocol + ] === 'undefined' + ) { + nextState[0].mixers[0].mixerProtocol = 'genericMidi' + } + return nextState + default: + return nextState + } +} diff --git a/shared/src/reducers/store.ts b/shared/src/reducers/store.ts new file mode 100644 index 00000000..8bb6e167 --- /dev/null +++ b/shared/src/reducers/store.ts @@ -0,0 +1,14 @@ +import { createStore } from 'redux' +import { IFaders } from './fadersReducer' +import { IChannels } from './channelsReducer' +import indexReducer from './indexReducer' +import { ISettings } from './settingsReducer' + +export interface IStore { + settings: Array + channels: Array + faders: Array +} + +export default createStore(indexReducer) +export { Store } from 'redux' \ No newline at end of file diff --git a/shared/src/utils/vu-server-types.ts b/shared/src/utils/vu-server-types.ts new file mode 100644 index 00000000..5eaea170 --- /dev/null +++ b/shared/src/utils/vu-server-types.ts @@ -0,0 +1,4 @@ +export enum VuType { + Channel = 'vuChannel', + Reduction = 'vuReduction', +} \ No newline at end of file diff --git a/storage/Default.x32 b/storage/Default.x32 new file mode 100644 index 00000000..9951650f --- /dev/null +++ b/storage/Default.x32 @@ -0,0 +1,4 @@ +{ + "sceneIndex": "0", + "sceneName": "default" +} diff --git a/storage/Preset 1.x32 b/storage/Preset 1.x32 new file mode 100644 index 00000000..285de3a9 --- /dev/null +++ b/storage/Preset 1.x32 @@ -0,0 +1,4 @@ +{ + "sceneIndex": "1", + "sceneName": "Preset 1" +} diff --git a/storage/Preset 2.x32 b/storage/Preset 2.x32 new file mode 100644 index 00000000..d14a903c --- /dev/null +++ b/storage/Preset 2.x32 @@ -0,0 +1,4 @@ +{ + "sceneIndex": "2", + "sceneName": "Preset 2" +} diff --git a/storage/Preset 3.x32 b/storage/Preset 3.x32 new file mode 100644 index 00000000..a9e0dd3e --- /dev/null +++ b/storage/Preset 3.x32 @@ -0,0 +1,4 @@ +{ + "sceneIndex": "3", + "sceneName": "Preset 3" +} diff --git a/storage/default-casparcg.ccg b/storage/default-casparcg.ccg index 726699fa..f9f7f590 100644 --- a/storage/default-casparcg.ccg +++ b/storage/default-casparcg.ccg @@ -1,86 +1,190 @@ { - "label": "Sofie CasparCG Example", - "fromMixer": { - "CHANNEL_VU": [ - ["/channel/1/stage/layer/51/audio/1/pFS", "/channel/1/stage/layer/51/audio/2/pFS"], - ["/channel/1/stage/layer/52/audio/1/pFS", "/channel/1/stage/layer/52/audio/2/pFS"], - ["/channel/1/stage/layer/53/audio/1/pFS", "/channel/1/stage/layer/53/audio/2/pFS"], - ["/channel/1/stage/layer/54/audio/1/pFS", "/channel/1/stage/layer/54/audio/2/pFS"], - ["/channel/1/stage/layer/55/audio/1/pFS", "/channel/1/stage/layer/55/audio/2/pFS"], - ["/channel/1/stage/layer/56/audio/1/pFS", "/channel/1/stage/layer/56/audio/2/pFS"] - ] - }, - "toMixer": { - "MONITOR_CHANNEL_FADER_LEVEL": [ - [ - { "channel": 2, "layer": 51 } - ], - [ - { "channel": 2, "layer": 52 } - ], - [ - { "channel": 2, "layer": 53 } - ], - [ - { "channel": 2, "layer": 54 } - ], - [ - { "channel": 2, "layer": 55 } - ], - [ - { "channel": 2, "layer": 56 } - ] - ], - "PGM_CHANNEL_FADER_LEVEL": [ - [ - { "channel": 1, "layer": 51 }, - { "channel": 3, "layer": 51 } - ], - [ - { "channel": 1, "layer": 52 }, - { "channel": 3, "layer": 52 } - ], - [ - { "channel": 1, "layer": 53 }, - { "channel": 3, "layer": 53 } - ], - [ - { "channel": 1, "layer": 54 }, - { "channel": 3, "layer": 54 } - ], - [ - { "channel": 1, "layer": 55 }, - { "channel": 3, "layer": 55 } - ], - [ - { "channel": 1, "layer": 56 }, - { "channel": 3, "layer": 56 } - ] - ] - }, - "channelLabels": [ - "RM1", - "RM2", - "RM3", - "RM4", - "RM5", - "MP1" - ], - "sourceOptions": { - "sources": [ - { "channel": 2, "layer": 51 }, - { "channel": 2, "layer": 52 }, - { "channel": 2, "layer": 53 }, - { "channel": 2, "layer": 54 }, - { "channel": 2, "layer": 55 }, - { "channel": 2, "layer": 56 } - ], - "options": { - "CHANNEL_LAYOUT": { - "1L-2R": "8ch2", - "1L-1R": "4ch-dleft", - "2L-2R": "4ch-dright" - } - } - } + "label": "Sofie CasparCG Example", + "fromMixer": { + "CHANNEL_VU": [ + [ + "/channel/1/stage/layer/51/audio/1/pFS", + "/channel/1/stage/layer/51/audio/2/pFS" + ], + [ + "/channel/1/stage/layer/52/audio/1/pFS", + "/channel/1/stage/layer/52/audio/2/pFS" + ], + [ + "/channel/1/stage/layer/53/audio/1/pFS", + "/channel/1/stage/layer/53/audio/2/pFS" + ], + [ + "/channel/1/stage/layer/54/audio/1/pFS", + "/channel/1/stage/layer/54/audio/2/pFS" + ], + [ + "/channel/1/stage/layer/55/audio/1/pFS", + "/channel/1/stage/layer/55/audio/2/pFS" + ], + [ + "/channel/1/stage/layer/56/audio/1/pFS", + "/channel/1/stage/layer/56/audio/2/pFS" + ] + ] + }, + "toMixer": { + "PFL_AUX_FADER_LEVEL": [ + [ + { + "channel": 2, + "layer": 51 + } + ], + [ + { + "channel": 2, + "layer": 52 + } + ], + [ + { + "channel": 2, + "layer": 53 + } + ], + [ + { + "channel": 2, + "layer": 54 + } + ], + [ + { + "channel": 2, + "layer": 55 + } + ], + [ + { + "channel": 2, + "layer": 56 + } + ] + ], + "PGM_CHANNEL_FADER_LEVEL": [ + [ + { + "channel": 1, + "layer": 51 + }, + { + "channel": 3, + "layer": 51 + } + ], + [ + { + "channel": 1, + "layer": 52 + }, + { + "channel": 3, + "layer": 52 + } + ], + [ + { + "channel": 1, + "layer": 53 + }, + { + "channel": 3, + "layer": 53 + } + ], + [ + { + "channel": 1, + "layer": 54 + }, + { + "channel": 3, + "layer": 54 + } + ], + [ + { + "channel": 1, + "layer": 55 + }, + { + "channel": 3, + "layer": 55 + } + ], + [ + { + "channel": 1, + "layer": 56 + }, + { + "channel": 3, + "layer": 56 + } + ] + ], + "CHANNEL_INPUT_SELECTOR": [ + { + "label": "1L-2R", + "mixerMessage": "8ch2" + }, + { + "label": "1L-1R", + "mixerMessage": "4ch-dleft" + }, + { + "label": "2L-2R", + "mixerMessage": "4ch-dright" + } + ] + }, + "channelLabels": [ + "RM1", + "RM2", + "RM3", + "RM4", + "RM5", + "MP1" + ], + "sourceOptions": { + "sources": [ + { + "channel": 2, + "layer": 51 + }, + { + "channel": 2, + "layer": 52 + }, + { + "channel": 2, + "layer": 53 + }, + { + "channel": 2, + "layer": 54 + }, + { + "channel": 2, + "layer": 55 + }, + { + "channel": 2, + "layer": 56 + } + ], + "options": { + "CHANNEL_LAYOUT": { + "1L-2R": "8ch2", + "1L-1R": "4ch-dleft", + "2L-2R": "4ch-dright" + } + } + } } diff --git a/storage/pages.json b/storage/pages.json new file mode 100644 index 00000000..60b7e02d --- /dev/null +++ b/storage/pages.json @@ -0,0 +1,10 @@ +[ + { + "id": "example", + "label": "LIVE", + "faders": [0, 2, 3, 4, 8, 13, 14, 15, 31] + }, + { "id": "studio", "label": "STUDIO", "faders": [0, 1, 4, 5, 9, 11] }, + { "id": "custom2", "label": "PLAYOUT", "faders": [7, 8, 10] }, + { "id": "custom3", "label": "Custom 3", "faders": [] } +] diff --git a/tsconfig-test.json b/tsconfig-test.json deleted file mode 100644 index 581c9979..00000000 --- a/tsconfig-test.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "compilerOptions": { - // Target latest version of ECMAScript. - "target": "es5", - // Search under node_modules for non-relative imports. - "moduleResolution": "node", - // Process & infer types from .js files. - "allowJs": false, - // Don't emit; allow Babel to transform files. - "noEmit": true, - // Enable strictest settings like strictNullChecks & noImplicitAny. - "strict": true, - // Disallow features that require cross-file information for emit. - "isolatedModules": false, - // Import non-ES modules as default imports. - "esModuleInterop": true, - //Support for jsx. - "jsx": "react", - // Check for "any" while converting to TS this can be turned off. - "noImplicitAny": true, - "module": "commonjs", - "allowSyntheticDefaultImports": true - }, - "include": [ - "src" - ] - } diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 5e70766a..00000000 --- a/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - // Target latest version of ECMAScript. - "target": "esnext", - // Search under node_modules for non-relative imports. - "moduleResolution": "node", - // Process & infer types from .js files. - "allowJs": false, - // Don't emit; allow Babel to transform files. - "noEmit": true, - // Enable strictest settings like strictNullChecks & noImplicitAny. - "strict": true, - // Disallow features that require cross-file information for emit. - "isolatedModules": false, - // Import non-ES modules as default imports. - "esModuleInterop": true, - //Support for jsx. - "jsx": "react", - // Check for "any" while converting to TS this can be turned off. - "noImplicitAny": true, - "module": "commonjs", - "allowSyntheticDefaultImports": true - }, - "include": [ - "client", "server" - ], - "exclude": [ - "node_modules", - "**/node_modules/*", - "dist" - ] - } diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000..20c2a52c --- /dev/null +++ b/tslint.json @@ -0,0 +1,20 @@ +{ + "extends": [ + "tslint-plugin-prettier", + "tslint:latest", + "tslint-config-prettier" + ], + "rules": { + "prettier": true, + "interface-name": false, + "object-literal-sort-keys": false, + "variable-name": [ + true, + "ban-keywords", + "check-format", + "allow-leading-underscore", + "require-const-for-all-caps" + ], + "no-bitwise": false + } +} diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index f4ecf20c..00000000 --- a/webpack.config.js +++ /dev/null @@ -1,59 +0,0 @@ -const webpack = require('webpack') -const path = require('path') -const HtmlWebpackPlugin = require('html-webpack-plugin') - -// Any directories you will be adding code/files into, need to be added to this array so webpack will pick them up -const defaultInclude = [ - path.resolve(__dirname, 'client'), - path.resolve(__dirname, 'server') -] - -module.exports = { - module: { - rules: [ - { - test:/\.css$/, - use:['style-loader', 'css-loader'] - }, - { - test: /\.(tsx?|ts)$/, - use: [{ loader: 'babel-loader' }], - include: defaultInclude - }, - { - test: /\.(jpe?g|png|gif)$/, - use: [{ loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]' }], - include: defaultInclude - }, - { - test: /\.(eot|svg|ttf|woff|woff2)$/, - use: [{ loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]' }], - include: defaultInclude - } - ] - }, - entry: "./client", - resolve: { - extensions: [ '.tsx', '.ts', '.js' ] - }, - output: { - // NB: Can also be "window", etc. - libraryTarget: "var" - }, - target: 'web', - plugins: [ - new HtmlWebpackPlugin({ - template: './client/index.ejs', - inject: true - }), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify('production') - }) - ], - stats: { - colors: true, - children: false, - chunks: false, - modules: false - } -} diff --git a/yarn.lock b/yarn.lock index fca5498a..07cad9a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,1047 +2,1023 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" - integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/core@^7.1.0", "@babel/core@^7.6.2": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.7.tgz#ee155d2e12300bcc0cff6a8ad46f2af5063803e9" - integrity sha512-jlSjuj/7z138NLZALxVgrx13AOtqip42ATZP7+kYl53GvDV6+4dCek1mVUo8z8c8Xnw/mx2q3d9HWh3griuesQ== - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.7" - "@babel/helpers" "^7.7.4" - "@babel/parser" "^7.7.7" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" +"7zip-bin@~5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.1.1.tgz#9274ec7460652f9c632c59addf24efb1684ef876" + integrity sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" + integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/compat-data@^7.21.5": + version "7.21.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.7.tgz#61caffb60776e49a57ba61a88f02bedd8714f6bc" + integrity sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.21.8": + version "7.21.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.8.tgz#2a8c7f0f53d60100ba4c32470ba0281c92aa9aa4" + integrity sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.21.5" + "@babel/helper-compilation-targets" "^7.21.5" + "@babel/helper-module-transforms" "^7.21.5" + "@babel/helpers" "^7.21.5" + "@babel/parser" "^7.21.8" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.5" + "@babel/types" "^7.21.5" convert-source-map "^1.7.0" debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.4.0", "@babel/generator@^7.7.4", "@babel/generator@^7.7.7": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.7.tgz#859ac733c44c74148e1a72980a64ec84b85f4f45" - integrity sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ== - dependencies: - "@babel/types" "^7.7.4" - jsesc "^2.5.1" - lodash "^4.17.13" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz#bb3faf1e74b74bd547e867e48f551fa6b098b6ce" - integrity sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og== - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz#5f73f2b28580e224b5b9bd03146a4015d6217f5f" - integrity sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-builder-react-jsx@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.7.4.tgz#da188d247508b65375b2c30cf59de187be6b0c66" - integrity sha512-kvbfHJNN9dg4rkEM4xn1s8d1/h6TYNvajy9L1wx4qLn9HFg0IkTsQi4rfBe92nxrPUFcMsHoMV+8rU7MJb3fCA== - dependencies: - "@babel/types" "^7.7.4" - esutils "^2.0.0" - -"@babel/helper-call-delegate@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz#621b83e596722b50c0066f9dc37d3232e461b801" - integrity sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA== - dependencies: - "@babel/helper-hoist-variables" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-create-class-features-plugin@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.7.4.tgz#fce60939fd50618610942320a8d951b3b639da2d" - integrity sha512-l+OnKACG4uiDHQ/aJT8dwpR+LhCJALxL0mJ6nzjB25e5IPwqV1VOsY7ah6UB1DG+VOXAIMtuC54rFJGiHkxjgA== - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-member-expression-to-functions" "^7.7.4" - "@babel/helper-optimise-call-expression" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - -"@babel/helper-create-regexp-features-plugin@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz#6d5762359fd34f4da1500e4cff9955b5299aaf59" - integrity sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A== - dependencies: - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.6.0" - -"@babel/helper-define-map@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz#2841bf92eb8bd9c906851546fe6b9d45e162f176" - integrity sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg== - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/types" "^7.7.4" - lodash "^4.17.13" - -"@babel/helper-explode-assignable-expression@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz#fa700878e008d85dc51ba43e9fb835cddfe05c84" - integrity sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg== - dependencies: - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-function-name@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz#ab6e041e7135d436d8f0a3eca15de5b67a341a2e" - integrity sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ== - dependencies: - "@babel/helper-get-function-arity" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-get-function-arity@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz#cb46348d2f8808e632f0ab048172130e636005f0" - integrity sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA== - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-hoist-variables@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz#612384e3d823fdfaaf9fce31550fe5d4db0f3d12" - integrity sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ== - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-member-expression-to-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz#356438e2569df7321a8326644d4b790d2122cb74" - integrity sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw== - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz#e5a92529f8888bf319a6376abfbd1cebc491ad91" - integrity sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ== - dependencies: - "@babel/types" "^7.7.4" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" -"@babel/helper-module-transforms@^7.7.4", "@babel/helper-module-transforms@^7.7.5": - version "7.7.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz#d044da7ffd91ec967db25cd6748f704b6b244835" - integrity sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw== +"@babel/generator@^7.21.5", "@babel/generator@^7.7.2": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.5.tgz#c0c0e5449504c7b7de8236d99338c3e2a340745f" + integrity sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w== dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-simple-access" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/types" "^7.7.4" - lodash "^4.17.13" + "@babel/types" "^7.21.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" -"@babel/helper-optimise-call-expression@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz#034af31370d2995242aa4df402c3b7794b2dcdf2" - integrity sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg== +"@babel/helper-compilation-targets@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz#631e6cc784c7b660417421349aac304c94115366" + integrity sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w== dependencies: - "@babel/types" "^7.7.4" + "@babel/compat-data" "^7.21.5" + "@babel/helper-validator-option" "^7.21.0" + browserslist "^4.21.3" + lru-cache "^5.1.1" + semver "^6.3.0" -"@babel/helper-plugin-utils@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" - integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== - -"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" - integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw== - dependencies: - lodash "^4.17.13" - -"@babel/helper-remap-async-to-generator@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz#c68c2407350d9af0e061ed6726afb4fff16d0234" - integrity sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.4" - "@babel/helper-wrap-function" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-replace-supers@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz#3c881a6a6a7571275a72d82e6107126ec9e2cdd2" - integrity sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.7.4" - "@babel/helper-optimise-call-expression" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-simple-access@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz#a169a0adb1b5f418cfc19f22586b2ebf58a9a294" - integrity sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A== - dependencies: - "@babel/template" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helper-split-export-declaration@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz#57292af60443c4a3622cf74040ddc28e68336fd8" - integrity sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug== - dependencies: - "@babel/types" "^7.7.4" - -"@babel/helper-wrap-function@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz#37ab7fed5150e22d9d7266e830072c0cdd8baace" - integrity sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg== - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/helpers@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.4.tgz#62c215b9e6c712dadc15a9a0dcab76c92a940302" - integrity sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg== - dependencies: - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/highlight@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" - integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== - dependencies: +"@babel/helper-environment-visitor@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz#c769afefd41d171836f7cb63e295bedf689d48ba" + integrity sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ== + +"@babel/helper-function-name@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" + integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== + dependencies: + "@babel/template" "^7.20.7" + "@babel/types" "^7.21.0" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.21.4": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af" + integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg== + dependencies: + "@babel/types" "^7.21.4" + +"@babel/helper-module-transforms@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz#d937c82e9af68d31ab49039136a222b17ac0b420" + integrity sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw== + dependencies: + "@babel/helper-environment-visitor" "^7.21.5" + "@babel/helper-module-imports" "^7.21.4" + "@babel/helper-simple-access" "^7.21.5" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.5" + "@babel/types" "^7.21.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz#345f2377d05a720a4e5ecfa39cbf4474a4daed56" + integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg== + +"@babel/helper-simple-access@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz#d697a7971a5c39eac32c7e63c0921c06c8a249ee" + integrity sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg== + dependencies: + "@babel/types" "^7.21.5" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd" + integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w== + +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/helper-validator-option@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" + integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== + +"@babel/helpers@^7.21.5": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.5.tgz#5bac66e084d7a4d2d9696bdf0175a93f7fb63c08" + integrity sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA== + dependencies: + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.5" + "@babel/types" "^7.21.5" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" chalk "^2.0.0" - esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.4", "@babel/parser@^7.7.7": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.7.tgz#1b886595419cf92d811316d5b715a53ff38b4937" - integrity sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6": + version "7.21.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.8.tgz#642af7d0333eab9c0ad70b14ac5e76dbde7bfdf8" + integrity sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA== -"@babel/plugin-proposal-async-generator-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz#0351c5ac0a9e927845fffd5b82af476947b7ce6d" - integrity sha512-1ypyZvGRXriY/QP668+s8sFr2mqinhkRDMPSQLNghCQE+GAkFtp+wkHVvg2+Hdki8gwP+NFzJBJ/N1BfzCCDEw== +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.7.4" - "@babel/plugin-syntax-async-generators" "^7.7.4" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-proposal-class-properties@^7.5.5": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.7.4.tgz#2f964f0cb18b948450362742e33e15211e77c2ba" - integrity sha512-EcuXeV4Hv1X3+Q1TsuOmyyxeTRiSqurGJ26+I/FW1WbymmRRapVORm6x1Zl3iDIHyRxEs+VXWp6qnlcfcJSbbw== +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-proposal-dynamic-import@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.4.tgz#dde64a7f127691758cbfed6cf70de0fa5879d52d" - integrity sha512-StH+nGAdO6qDB1l8sZ5UBV8AC3F2VW2I8Vfld73TMKyptMU9DY5YsJAS8U81+vEtxcH3Y/La0wG0btDrhpnhjQ== +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.7.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-proposal-json-strings@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz#7700a6bfda771d8dc81973249eac416c6b4c697d" - integrity sha512-wQvt3akcBTfLU/wYoqm/ws7YOAQKu8EVJEvHip/mzkNtjaclQoCCIqKXFP5/eyfnfbQCDV3OLRIK3mIVyXuZlw== +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.7.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.6.2", "@babel/plugin-proposal-object-rest-spread@^7.7.7": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.7.tgz#9f27075004ab99be08c5c1bd653a2985813cb370" - integrity sha512-3qp9I8lelgzNedI3hrhkvhaEYree6+WHnyA/q4Dza9z7iEIs1eyhWyJnetk3jJ69RT0AT4G0UhEGwyGFJ7GUuQ== +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.7.4" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-proposal-optional-catch-binding@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz#ec21e8aeb09ec6711bc0a39ca49520abee1de379" - integrity sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w== +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz#f264ed7bf40ffc9ec239edabc17a50c4f5b6fea2" + integrity sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" + "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-proposal-unicode-property-regex@^7.7.7": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.7.tgz#433fa9dac64f953c12578b29633f456b68831c4e" - integrity sha512-80PbkKyORBUVm1fbTLrHpYdJxMThzM1UqFGh0ALEhO9TYbG86Ah9zQYAB/84axz2vcxefDLdZwWwZNlYARlu9w== +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-async-generators@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz#331aaf310a10c80c44a66b238b6e49132bd3c889" - integrity sha512-Li4+EjSpBgxcsmeEF8IFcfV/+yJGxHXDirDkEoyFjumuwbmfCVHUt0HuowD/iGM7OhIRyXJH9YXxqiH6N815+g== +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-dynamic-import@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz#29ca3b4415abfe4a5ec381e903862ad1a54c3aec" - integrity sha512-jHQW0vbRGvwQNgyVxwDh4yuXu4bH1f5/EICJLAhl1SblLs2CDhrsmCk+v5XLdE9wxtAFRyxx+P//Iw+a5L/tTg== +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-json-strings@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz#86e63f7d2e22f9e27129ac4e83ea989a382e86cc" - integrity sha512-QpGupahTQW1mHRXddMG5srgpHWqRLwJnJZKXTigB9RPFCCGbDGCgBeM/iC82ICXp414WeYx/tD54w7M2qRqTMg== +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.7.4.tgz#dab2b56a36fb6c3c222a1fbc71f7bf97f327a9ec" - integrity sha512-wuy6fiMe9y7HeZBWXYCGt2RGxZOj0BImZ9EyXJVnVGBKO/Br592rbR3rtIQn0eQhAk9vqaKP5n8tVqEFBQMfLg== +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0", "@babel/plugin-syntax-object-rest-spread@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz#47cf220d19d6d0d7b154304701f468fc1cc6ff46" - integrity sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg== +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz#a3e38f59f4b6233867b4a92dcb0ee05b2c334aa6" - integrity sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ== +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-top-level-await@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.4.tgz#bd7d8fa7b9fee793a36e4027fd6dd1aa32f946da" - integrity sha512-wdsOw0MvkL1UIgiQ/IFr3ETcfv1xb8RMM0H9wbiDyLaJFyiDg5oZvDLCXosIXmFeIlweML5iOBXAkqddkYNizg== +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz#2751948e9b7c6d771a8efa59340c15d4a2891ff8" + integrity sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-typescript@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.7.4.tgz#5d037ffa10f3b25a16f32570ebbe7a8c2efa304b" - integrity sha512-77blgY18Hud4NM1ggTA8xVT/dBENQf17OpiToSa2jSmEY3fWXD2jwrdVlO4kq5yzUTeF15WSQ6b4fByNvJcjpQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-arrow-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz#76309bd578addd8aee3b379d809c802305a98a12" - integrity sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-async-to-generator@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz#694cbeae6d613a34ef0292713fa42fb45c4470ba" - integrity sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg== - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.7.4" + "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-transform-block-scoped-functions@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz#d0d9d5c269c78eaea76227ace214b8d01e4d837b" - integrity sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ== +"@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.19.4", "@babel/runtime@^7.20.6", "@babel/runtime@^7.21.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" + integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + regenerator-runtime "^0.13.11" -"@babel/plugin-transform-block-scoping@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz#200aad0dcd6bb80372f94d9e628ea062c58bf224" - integrity sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg== +"@babel/template@^7.20.7", "@babel/template@^7.3.3": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" + integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.13" + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" -"@babel/plugin-transform-classes@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz#c92c14be0a1399e15df72667067a8f510c9400ec" - integrity sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg== +"@babel/traverse@^7.21.5", "@babel/traverse@^7.7.2": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.5.tgz#ad22361d352a5154b498299d523cf72998a4b133" + integrity sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw== dependencies: - "@babel/helper-annotate-as-pure" "^7.7.4" - "@babel/helper-define-map" "^7.7.4" - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-optimise-call-expression" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" + "@babel/code-frame" "^7.21.4" + "@babel/generator" "^7.21.5" + "@babel/helper-environment-visitor" "^7.21.5" + "@babel/helper-function-name" "^7.21.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.21.5" + "@babel/types" "^7.21.5" + debug "^4.1.0" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz#e856c1628d3238ffe12d668eb42559f79a81910d" - integrity sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ== +"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.6.1", "@babel/types@^7.9.6": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.5.tgz#18dfbd47c39d3904d5db3d3dc2cc80bedb60e5b6" + integrity sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-destructuring@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz#2b713729e5054a1135097b6a67da1b6fe8789267" - integrity sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-string-parser" "^7.21.5" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" -"@babel/plugin-transform-dotall-regex@^7.7.7": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.7.tgz#3e9713f1b69f339e87fa796b097d73ded16b937b" - integrity sha512-b4in+YlTeE/QmTgrllnb3bHA0HntYvjz8O3Mcbx75UBPJA2xhb5A8nle498VhxSXJHQefjtQxpnLPehDJ4TRlg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@babel/plugin-transform-duplicate-keys@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz#3d21731a42e3f598a73835299dd0169c3b90ac91" - integrity sha512-g1y4/G6xGWMD85Tlft5XedGaZBCIVN+/P0bs6eabmcPP9egFleMAo65OOjlhcz1njpwagyY3t0nsQC9oTFegJA== +"@develar/schema-utils@~2.6.5": + version "2.6.5" + resolved "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.6.5.tgz#3ece22c5838402419a6e0425f85742b961d9b6c6" + integrity sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + ajv "^6.12.0" + ajv-keywords "^3.4.1" -"@babel/plugin-transform-exponentiation-operator@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz#dd30c0191e3a1ba19bcc7e389bdfddc0729d5db9" - integrity sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@babel/plugin-transform-for-of@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz#248800e3a5e507b1f103d8b4ca998e77c63932bc" - integrity sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA== +"@electron/get@^1.13.0": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.14.1.tgz#16ba75f02dffb74c23965e72d617adc721d27f40" + integrity sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + debug "^4.1.1" + env-paths "^2.2.0" + fs-extra "^8.1.0" + got "^9.6.0" + progress "^2.0.3" + semver "^6.2.0" + sumchecker "^3.0.1" + optionalDependencies: + global-agent "^3.0.0" + global-tunnel-ng "^2.7.1" -"@babel/plugin-transform-function-name@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz#75a6d3303d50db638ff8b5385d12451c865025b1" - integrity sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g== - dependencies: - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" +"@electron/universal@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.0.5.tgz#b812340e4ef21da2b3ee77b2b4d35c9b86defe37" + integrity sha512-zX9O6+jr2NMyAdSkwEUlyltiI4/EBLu2Ls/VD3pUQdi3cAYeYfdQnT2AJJ38HE4QxLccbU13LSpccw1IWlkyag== + dependencies: + "@malept/cross-spawn-promise" "^1.1.0" + asar "^3.0.3" + debug "^4.3.1" + dir-compare "^2.4.0" + fs-extra "^9.0.1" + +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" + 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.2.0" + +"@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" + +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== + +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/react@^11.8.1": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.0.tgz#408196b7ef8729d8ad08fc061b03b046d1460e02" + integrity sha512-ZSK3ZJsNkwfjT3JpDAWJZlrGD81Z3ytNDsxw1LKq1o+xkmO5pnWfr6gmCC8gHEFf3nSSX/09YrG67jybNPxSUw== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + hoist-non-react-statics "^3.3.1" + +"@emotion/serialize@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51" + integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA== + dependencies: + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" + csstype "^3.0.2" + +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== + +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== -"@babel/plugin-transform-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz#27fe87d2b5017a2a5a34d1c41a6b9f6a6262643e" - integrity sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== -"@babel/plugin-transform-member-expression-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz#aee127f2f3339fc34ce5e3055d7ffbf7aa26f19a" - integrity sha512-9VMwMO7i69LHTesL0RdGy93JU6a+qOPuvB4F4d0kR0zyVjJRVJRaoaGjhtki6SzQUu8yen/vxPKN6CWnCUw6bA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== -"@babel/plugin-transform-modules-amd@^7.7.5": - version "7.7.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.5.tgz#39e0fb717224b59475b306402bb8eedab01e729c" - integrity sha512-CT57FG4A2ZUNU1v+HdvDSDrjNWBrtCmSH6YbbgN3Lrf0Di/q/lWRxZrE72p3+HCCz9UjfZOEBdphgC0nzOS6DQ== - dependencies: - "@babel/helper-module-transforms" "^7.7.5" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" +"@floating-ui/core@^1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.2.6.tgz#d21ace437cc919cdd8f1640302fa8851e65e75c0" + integrity sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg== -"@babel/plugin-transform-modules-commonjs@^7.7.5": - version "7.7.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz#1d27f5eb0bcf7543e774950e5b2fa782e637b345" - integrity sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q== +"@floating-ui/dom@^1.0.1": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.2.8.tgz#aee0f6ccc0787ab8fe741487a6e5e95b7b125375" + integrity sha512-XLwhYV90MxiHDq6S0rzFZj00fnDM+A1R9jhSioZoMsa7G0Q0i+Q4x40ajR8FHSdYDE1bgjG45mIWe6jtv9UPmg== dependencies: - "@babel/helper-module-transforms" "^7.7.5" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.7.4" - babel-plugin-dynamic-import-node "^2.3.0" + "@floating-ui/core" "^1.2.6" -"@babel/plugin-transform-modules-systemjs@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz#cd98152339d3e763dfe838b7d4273edaf520bb30" - integrity sha512-y2c96hmcsUi6LrMqvmNDPBBiGCiQu0aYqpHatVVu6kD4mFEXKjyNxd/drc18XXAf9dv7UXjrZwBVmTTGaGP8iw== +"@ioredis/commands@^1.1.1": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" + integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + 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" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== dependencies: - "@babel/helper-hoist-variables" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" + 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" -"@babel/plugin-transform-modules-umd@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz#1027c355a118de0aae9fee00ad7813c584d9061f" - integrity sha512-u2B8TIi0qZI4j8q4C51ktfO7E3cQ0qnaXFI1/OXITordD40tt17g/sXqgNNCcMTcBFKrUPcGDx+TBJuZxLx7tw== - dependencies: - "@babel/helper-module-transforms" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.5.0.tgz#593a6c5c0d3f75689835f1b3b4688c4f8544cb57" + integrity sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ== + dependencies: + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + slash "^3.0.0" + +"@jest/core@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.5.0.tgz#76674b96904484e8214614d17261cc491e5f1f03" + integrity sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ== + dependencies: + "@jest/console" "^29.5.0" + "@jest/reporters" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.5.0" + jest-config "^29.5.0" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-resolve-dependencies "^29.5.0" + jest-runner "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" + jest-watcher "^29.5.0" + micromatch "^4.0.4" + pretty-format "^29.5.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.5.0.tgz#9152d56317c1fdb1af389c46640ba74ef0bb4c65" + integrity sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ== + dependencies: + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + jest-mock "^29.5.0" + +"@jest/expect-utils@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" + integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== + dependencies: + jest-get-type "^29.4.3" + +"@jest/expect@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.5.0.tgz#80952f5316b23c483fbca4363ce822af79c38fba" + integrity sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g== + dependencies: + expect "^29.5.0" + jest-snapshot "^29.5.0" + +"@jest/fake-timers@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.5.0.tgz#d4d09ec3286b3d90c60bdcd66ed28d35f1b4dc2c" + integrity sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg== + dependencies: + "@jest/types" "^29.5.0" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-util "^29.5.0" + +"@jest/globals@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.5.0.tgz#6166c0bfc374c58268677539d0c181f9c1833298" + integrity sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ== + dependencies: + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/types" "^29.5.0" + jest-mock "^29.5.0" + +"@jest/reporters@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.5.0.tgz#985dfd91290cd78ddae4914ba7921bcbabe8ac9b" + integrity sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@jridgewell/trace-mapping" "^0.3.15" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + 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-message-util "^29.5.0" + jest-util "^29.5.0" + jest-worker "^29.5.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" + integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== + dependencies: + "@sinclair/typebox" "^0.25.16" + +"@jest/source-map@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" + integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.15" + callsites "^3.0.0" + graceful-fs "^4.2.9" -"@babel/plugin-transform-named-capturing-groups-regex@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz#fb3bcc4ee4198e7385805007373d6b6f42c98220" - integrity sha512-jBUkiqLKvUWpv9GLSuHUFYdmHg0ujC1JEYoZUfeOOfNydZXp1sXObgyPatpcwjWgsdBGsagWW0cdJpX/DO2jMw== +"@jest/test-result@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.5.0.tgz#7c856a6ca84f45cc36926a4e9c6b57f1973f1408" + integrity sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" + "@jest/console" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz#34d7d82d3081abd523dbddc038a3ddcb9f6d3cc4" + integrity sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ== + dependencies: + "@jest/test-result" "^29.5.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.5.0" + slash "^3.0.0" + +"@jest/transform@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.5.0.tgz#cf9c872d0965f0cbd32f1458aa44a2b1988b00f9" + integrity sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.5.0" + "@jridgewell/trace-mapping" "^0.3.15" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.5.0" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" + integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== + dependencies: + "@jest/schemas" "^29.4.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" -"@babel/plugin-transform-new-target@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz#4a0753d2d60639437be07b592a9e58ee00720167" - integrity sha512-CnPRiNtOG1vRodnsyGX37bHQleHE14B9dnnlgSeEs3ek3fHN1A1SScglTCg1sfbe7sRQ2BUcpgpTpWSfMKz3gg== +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" -"@babel/plugin-transform-object-super@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz#48488937a2d586c0148451bf51af9d7dda567262" - integrity sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.7.4" +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== -"@babel/plugin-transform-parameters@^7.7.7": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.7.tgz#7a884b2460164dc5f194f668332736584c760007" - integrity sha512-OhGSrf9ZBrr1fw84oFXj5hgi8Nmg+E2w5L7NhnG0lPvpDtqd7dbyilM2/vR8CKbJ907RyxPh2kj6sBCSSfI9Ew== - dependencies: - "@babel/helper-call-delegate" "^7.7.4" - "@babel/helper-get-function-arity" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@babel/plugin-transform-property-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz#2388d6505ef89b266103f450f9167e6bd73f98c2" - integrity sha512-MatJhlC4iHsIskWYyawl53KuHrt+kALSADLQQ/HkhTjX954fkxIEh4q5slL4oRAnsm/eDoZ4q0CIZpcqBuxhJQ== +"@jridgewell/source-map@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" + integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" -"@babel/plugin-transform-react-display-name@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.7.4.tgz#9f2b80b14ebc97eef4a9b29b612c58ed9c0d10dd" - integrity sha512-sBbIvqYkthai0X0vkD2xsAwluBp+LtNHH+/V4a5ydifmTtb8KOVOlrMIk/MYmIc4uTYDnjZUHQildYNo36SRJw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@babel/plugin-transform-react-jsx-self@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.7.4.tgz#81b8fbfd14b2215e8f1c2c3adfba266127b0231c" - integrity sha512-PWYjSfqrO273mc1pKCRTIJXyqfc9vWYBax88yIhQb+bpw3XChVC7VWS4VwRVs63wFHKxizvGSd00XEr+YB9Q2A== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.7.4" +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@babel/plugin-transform-react-jsx-source@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.7.4.tgz#8994b1bf6014b133f5a46d3b7d1ee5f5e3e72c10" - integrity sha512-5ZU9FnPhqtHsOXxutRtXZAzoEJwDaP32QcobbMP1/qt7NYcsCNK8XgzJcJfoEr/ZnzVvUNInNjIW22Z6I8p9mg== +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.7.4" + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" -"@babel/plugin-transform-react-jsx@^7.7.4": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.7.7.tgz#5cbaa7445b4a09f774029f3cc7bb448ff3122a5d" - integrity sha512-SlPjWPbva2+7/ZJbGcoqjl4LsQaLpKEzxW9hcxU7675s24JmdotJOSJ4cgAbV82W3FcZpHIGmRZIlUL8ayMvjw== +"@julusian/freetype2@^1.1.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@julusian/freetype2/-/freetype2-1.1.2.tgz#c4a4030785214ad1f9b833d78b8571b78afe76a0" + integrity sha512-Y7JCIE2EIvQtne3J1FY5eweD4GcCGG3nX323Yq2AOGus9/1PGjcxTv8OWL34ONt11kuTMItEt9klddZzIeUHvQ== dependencies: - "@babel/helper-builder-react-jsx" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.7.4" + node-addon-api "^5.0.0" + pkg-prebuilds "^0.2.1" -"@babel/plugin-transform-regenerator@^7.7.5": - version "7.7.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz#3a8757ee1a2780f390e89f246065ecf59c26fce9" - integrity sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw== +"@malept/cross-spawn-promise@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d" + integrity sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ== dependencies: - regenerator-transform "^0.14.0" + cross-spawn "^7.0.1" -"@babel/plugin-transform-reserved-words@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.7.4.tgz#6a7cf123ad175bb5c69aec8f6f0770387ed3f1eb" - integrity sha512-OrPiUB5s5XvkCO1lS7D8ZtHcswIC57j62acAnJZKqGGnHP+TIc/ljQSrgdX/QyOTdEK5COAhuc820Hi1q2UgLQ== +"@malept/flatpak-bundler@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz#e8a32c30a95d20c2b1bb635cc580981a06389858" + integrity sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + debug "^4.1.1" + fs-extra "^9.0.0" + lodash "^4.17.15" + tmp-promise "^3.0.2" -"@babel/plugin-transform-shorthand-properties@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz#74a0a9b2f6d67a684c6fbfd5f0458eb7ba99891e" - integrity sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" +"@octetstream/promisify@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@octetstream/promisify/-/promisify-2.0.2.tgz#29ac3bd7aefba646db670227f895d812c1a19615" + integrity sha512-7XHoRB61hxsz8lBQrjC1tq/3OEIgpvGWg6DKAdwi7WRzruwkmsdwmOoUXbU4Dtd4RSOMDwed0SkP3y8UlMt1Bg== -"@babel/plugin-transform-spread@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz#aa673b356fe6b7e70d69b6e33a17fef641008578" - integrity sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q== +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@serialport/binding-mock@10.2.2": + version "10.2.2" + resolved "https://registry.yarnpkg.com/@serialport/binding-mock/-/binding-mock-10.2.2.tgz#d322a8116a97806addda13c62f50e73d16125874" + integrity sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw== + dependencies: + "@serialport/bindings-interface" "^1.2.1" + debug "^4.3.3" + +"@serialport/bindings-cpp@10.8.0": + version "10.8.0" + resolved "https://registry.yarnpkg.com/@serialport/bindings-cpp/-/bindings-cpp-10.8.0.tgz#79507b57022ac264e963e7fbf3647a3821569a20" + integrity sha512-OMQNJz5kJblbmZN5UgJXLwi2XNtVLxSKmq5VyWuXQVsUIJD4l9UGHnLPqM5LD9u3HPZgDI5w7iYN7gxkQNZJUw== + dependencies: + "@serialport/bindings-interface" "1.2.2" + "@serialport/parser-readline" "^10.2.1" + debug "^4.3.2" + node-addon-api "^5.0.0" + node-gyp-build "^4.3.0" + +"@serialport/bindings-interface@1.2.2", "@serialport/bindings-interface@^1.2.1": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz#c4ae9c1c85e26b02293f62f37435478d90baa460" + integrity sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA== + +"@serialport/parser-byte-length@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-byte-length/-/parser-byte-length-10.5.0.tgz#f3d4c1c7923222df2f3d3c7c8aaaa207fe373b49" + integrity sha512-eHhr4lHKboq1OagyaXAqkemQ1XyoqbLQC8XJbvccm95o476TmEdW5d7AElwZV28kWprPW68ZXdGF2VXCkJgS2w== + +"@serialport/parser-cctalk@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-cctalk/-/parser-cctalk-10.5.0.tgz#0ee88db0768a361b7cfb9a394b74e480c38e1992" + integrity sha512-Iwsdr03xmCKAiibLSr7b3w6ZUTBNiS+PwbDQXdKU/clutXjuoex83XvsOtYVcNZmwJlVNhAUbkG+FJzWwIa4DA== + +"@serialport/parser-delimiter@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-delimiter/-/parser-delimiter-10.5.0.tgz#b0d93100cdfd0619d020a427d652495073f3b828" + integrity sha512-/uR/yT3jmrcwnl2FJU/2ySvwgo5+XpksDUR4NF/nwTS5i3CcuKS+FKi/tLzy1k8F+rCx5JzpiK+koqPqOUWArA== + +"@serialport/parser-inter-byte-timeout@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.5.0.tgz#8665ee5e6138f794ac055e83ef2d1c3653a577c0" + integrity sha512-WPvVlSx98HmmUF9jjK6y9mMp3Wnv6JQA0cUxLeZBgS74TibOuYG3fuUxUWGJALgAXotOYMxfXSezJ/vSnQrkhQ== + +"@serialport/parser-packet-length@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-packet-length/-/parser-packet-length-10.5.0.tgz#4c4d733bdff8cc4749f2bd750e42e66f8f478def" + integrity sha512-jkpC/8w4/gUBRa2Teyn7URv1D7T//0lGj27/4u9AojpDVXsR6dtdcTG7b7dNirXDlOrSLvvN7aS5/GNaRlEByw== + +"@serialport/parser-readline@10.5.0", "@serialport/parser-readline@^10.2.1": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-readline/-/parser-readline-10.5.0.tgz#df23365ae7f45679b1735deae26f72ba42802862" + integrity sha512-0aXJknodcl94W9zSjvU+sLdXiyEG2rqjQmvBWZCr8wJZjWEtv3RgrnYiWq4i2OTOyC8C/oPK8ZjpBjQptRsoJQ== + dependencies: + "@serialport/parser-delimiter" "10.5.0" + +"@serialport/parser-ready@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-ready/-/parser-ready-10.5.0.tgz#1d9029f57b1abd664cb468e21bfccf7b44c6e8ea" + integrity sha512-QIf65LTvUoxqWWHBpgYOL+soldLIIyD1bwuWelukem2yDZVWwEjR288cLQ558BgYxH4U+jLAQahhqoyN1I7BaA== + +"@serialport/parser-regex@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-regex/-/parser-regex-10.5.0.tgz#f98eab6e3d9bc99086269e9acf39a82db36d245f" + integrity sha512-9jnr9+PCxRoLjtGs7uxwsFqvho+rxuJlW6ZWSB7oqfzshEZWXtTJgJRgac/RuLft4hRlrmRz5XU40i3uoL4HKw== + +"@serialport/parser-slip-encoder@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-slip-encoder/-/parser-slip-encoder-10.5.0.tgz#cb79ac0fda1fc87f049690ff7b498c787da67991" + integrity sha512-wP8m+uXQdkWSa//3n+VvfjLthlabwd9NiG6kegf0fYweLWio8j4pJRL7t9eTh2Lbc7zdxuO0r8ducFzO0m8CQw== + +"@serialport/parser-spacepacket@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/parser-spacepacket/-/parser-spacepacket-10.5.0.tgz#2fc077c0ec16a9532c511ad5f2ab12d588796bc7" + integrity sha512-BEZ/HAEMwOd8xfuJSeI/823IR/jtnThovh7ils90rXD4DPL1ZmrP4abAIEktwe42RobZjIPfA4PaVfyO0Fjfhg== + +"@serialport/stream@10.5.0": + version "10.5.0" + resolved "https://registry.yarnpkg.com/@serialport/stream/-/stream-10.5.0.tgz#cda8fb3e8d03094b0962a3d14b73adfcd591be58" + integrity sha512-gbcUdvq9Kyv2HsnywS7QjnEB28g+6OGB5Z8TLP7X+UPpoMIWoUsoQIq5Kt0ZTgMoWn3JGM2lqwTsSHF+1qhniA== + dependencies: + "@serialport/bindings-interface" "1.2.2" + debug "^4.3.2" + +"@sinclair/typebox@^0.25.16": + version "0.25.24" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" + integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@sinonjs/commons@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" + integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + type-detect "4.0.8" -"@babel/plugin-transform-sticky-regex@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz#ffb68c05090c30732076b1285dc1401b404a123c" - integrity sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A== +"@sinonjs/fake-timers@^10.0.2": + version "10.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.1.0.tgz#3595e42b3f0a7df80a9681cf58d8cb418eac1e99" + integrity sha512-w1qd368vtrwttm1PRJWPW1QHlbmHrVDGs1eBH/jZvRPUFS4MNXV9Q33EQdjOdeAxZ7O8+3wM7zxztm2nfUSyKw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" + "@sinonjs/commons" "^3.0.0" -"@babel/plugin-transform-template-literals@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz#1eb6411736dd3fe87dbd20cc6668e5121c17d604" - integrity sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" +"@socket.io/component-emitter@~3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" + integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== -"@babel/plugin-transform-typeof-symbol@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz#3174626214f2d6de322882e498a38e8371b2140e" - integrity sha512-KQPUQ/7mqe2m0B8VecdyaW5XcQYaePyl9R7IsKd+irzj6jvbhoGnRE+M0aNkyAzI07VfUQ9266L5xMARitV3wg== +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + defer-to-connect "^1.0.1" -"@babel/plugin-transform-typescript@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.7.4.tgz#2974fd05f4e85c695acaf497f432342de9fc0636" - integrity sha512-X8e3tcPEKnwwPVG+vP/vSqEShkwODOEeyQGod82qrIuidwIrfnsGn11qPM1jBLF4MqguTXXYzm58d0dY+/wdpg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-typescript" "^7.7.4" +"@tv2media/logger@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@tv2media/logger/-/logger-2.0.1.tgz#da1a8d7c8b60b1c6e654dccacc45150a0a2de45f" + integrity sha512-GqIAGytXF3lBvqz/wLwetOdhPFDyvhIJxJ+ivoiYyMLLUHHJYnjCqd5T2pAwskcv3eSilCqm+2fTy88SlUoSLA== -"@babel/plugin-transform-unicode-regex@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz#a3c0f65b117c4c81c5b6484f2a5e7b95346b83ae" - integrity sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw== +"@types/asn1@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@types/asn1/-/asn1-0.2.0.tgz#23b568688b321740bd4eafef49e6b13ffc101b31" + integrity sha512-5TMxIpYbIA9c1J0hYQjQDX3wr+rTgQEAXaW2BI8ECM8FO53wSW4HFZplTalrKSHuZUc76NtXcePRhwuOHqGD5g== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" + "@types/node" "*" -"@babel/preset-env@^7.6.2": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.7.tgz#c294167b91e53e7e36d820e943ece8d0c7fe46ac" - integrity sha512-pCu0hrSSDVI7kCVUOdcMNQEbOPJ52E+LrQ14sN8uL2ALfSqePZQlKrOy+tM4uhEdYlCHi4imr8Zz2cZe9oSdIg== - dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.7.4" - "@babel/plugin-proposal-dynamic-import" "^7.7.4" - "@babel/plugin-proposal-json-strings" "^7.7.4" - "@babel/plugin-proposal-object-rest-spread" "^7.7.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.7.4" - "@babel/plugin-proposal-unicode-property-regex" "^7.7.7" - "@babel/plugin-syntax-async-generators" "^7.7.4" - "@babel/plugin-syntax-dynamic-import" "^7.7.4" - "@babel/plugin-syntax-json-strings" "^7.7.4" - "@babel/plugin-syntax-object-rest-spread" "^7.7.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" - "@babel/plugin-syntax-top-level-await" "^7.7.4" - "@babel/plugin-transform-arrow-functions" "^7.7.4" - "@babel/plugin-transform-async-to-generator" "^7.7.4" - "@babel/plugin-transform-block-scoped-functions" "^7.7.4" - "@babel/plugin-transform-block-scoping" "^7.7.4" - "@babel/plugin-transform-classes" "^7.7.4" - "@babel/plugin-transform-computed-properties" "^7.7.4" - "@babel/plugin-transform-destructuring" "^7.7.4" - "@babel/plugin-transform-dotall-regex" "^7.7.7" - "@babel/plugin-transform-duplicate-keys" "^7.7.4" - "@babel/plugin-transform-exponentiation-operator" "^7.7.4" - "@babel/plugin-transform-for-of" "^7.7.4" - "@babel/plugin-transform-function-name" "^7.7.4" - "@babel/plugin-transform-literals" "^7.7.4" - "@babel/plugin-transform-member-expression-literals" "^7.7.4" - "@babel/plugin-transform-modules-amd" "^7.7.5" - "@babel/plugin-transform-modules-commonjs" "^7.7.5" - "@babel/plugin-transform-modules-systemjs" "^7.7.4" - "@babel/plugin-transform-modules-umd" "^7.7.4" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.7.4" - "@babel/plugin-transform-new-target" "^7.7.4" - "@babel/plugin-transform-object-super" "^7.7.4" - "@babel/plugin-transform-parameters" "^7.7.7" - "@babel/plugin-transform-property-literals" "^7.7.4" - "@babel/plugin-transform-regenerator" "^7.7.5" - "@babel/plugin-transform-reserved-words" "^7.7.4" - "@babel/plugin-transform-shorthand-properties" "^7.7.4" - "@babel/plugin-transform-spread" "^7.7.4" - "@babel/plugin-transform-sticky-regex" "^7.7.4" - "@babel/plugin-transform-template-literals" "^7.7.4" - "@babel/plugin-transform-typeof-symbol" "^7.7.4" - "@babel/plugin-transform-unicode-regex" "^7.7.4" - "@babel/types" "^7.7.4" - browserslist "^4.6.0" - core-js-compat "^3.6.0" - invariant "^2.2.2" - js-levenshtein "^1.1.3" - semver "^5.5.0" - -"@babel/preset-react@^7.0.0": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.7.4.tgz#3fe2ea698d8fb536d8e7881a592c3c1ee8bf5707" - integrity sha512-j+vZtg0/8pQr1H8wKoaJyGL2IEk3rG/GIvua7Sec7meXVIvGycihlGMx5xcU00kqCJbwzHs18xTu3YfREOqQ+g== +"@types/babel__core@^7.1.14": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" + integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.7.4" - "@babel/plugin-transform-react-jsx" "^7.7.4" - "@babel/plugin-transform-react-jsx-self" "^7.7.4" - "@babel/plugin-transform-react-jsx-source" "^7.7.4" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" -"@babel/preset-typescript@^7.6.0": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.7.7.tgz#69ddea54e8b4e491ccbf94147e673b2ac6e11e2e" - integrity sha512-Apg0sCTovsSA+pEaI8efnA44b9x4X/7z4P8vsWMiN8rSUaM4y4+Shl5NMWnMl6njvt96+CEb6jwpXAKYAVCSQA== +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.7.4" + "@babel/types" "^7.0.0" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.7.tgz#194769ca8d6d7790ec23605af9ee3e42a0aa79cf" - integrity sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA== +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== dependencies: - regenerator-runtime "^0.13.2" + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" -"@babel/template@^7.4.0", "@babel/template@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.4.tgz#428a7d9eecffe27deac0a98e23bf8e3675d2a77b" - integrity sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw== +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.18.5" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.5.tgz#c107216842905afafd3b6e774f6f935da6f5db80" + integrity sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q== dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.7.4" - "@babel/types" "^7.7.4" - -"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.4.tgz#9c1e7c60fb679fe4fcfaa42500833333c2058558" - integrity sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw== - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.7.4" - "@babel/helper-function-name" "^7.7.4" - "@babel/helper-split-export-declaration" "^7.7.4" - "@babel/parser" "^7.7.4" - "@babel/types" "^7.7.4" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.13" + "@babel/types" "^7.3.0" -"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.4.tgz#516570d539e44ddf308c07569c258ff94fde9193" - integrity sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA== +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== dependencies: - esutils "^2.0.2" - lodash "^4.17.13" - to-fast-properties "^2.0.0" + "@types/connect" "*" + "@types/node" "*" -"@cnakazawa/watch@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" - integrity sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA== +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" + "@types/node" "*" -"@elastic/elasticsearch@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.5.0.tgz#a54b07001e1a3912792bf9f34e6ec6a4fe0aef0c" - integrity sha512-ahzu451ppXepQMb3Zr8eFfWn8QR7yCcUWQjU1dS4X63Ctin0GNwwSPertt4WwDkm6MnZ25o932wAEgyMFLwzdA== - dependencies: - debug "^4.1.1" - decompress-response "^4.2.0" - into-stream "^5.1.0" - ms "^2.1.1" - once "^1.4.0" - pump "^3.0.0" +"@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== -"@emotion/cache@^10.0.27", "@emotion/cache@^10.0.9": - version "10.0.27" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.27.tgz#7895db204e2c1a991ae33d51262a3a44f6737303" - integrity sha512-Zp8BEpbMunFsTcqAK4D7YTm3MvCp1SekflSLJH8lze2fCcSZ/yMkXHo8kb3t1/1Tdd3hAqf3Fb7z9VZ+FMiC9w== +"@types/cors@^2.8.12": + version "2.8.13" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94" + integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA== dependencies: - "@emotion/sheet" "0.9.4" - "@emotion/stylis" "0.8.5" - "@emotion/utils" "0.11.3" - "@emotion/weak-memoize" "0.2.5" + "@types/node" "*" -"@emotion/core@^10.0.9": - version "10.0.27" - resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.27.tgz#7c3f78be681ab2273f3bf11ca3e2edc4a9dd1fdc" - integrity sha512-XbD5R36pVbohQMnKfajHv43g8EbN4NHdF6Zh9zg/C0nr0jqwOw3gYnC07Xj3yG43OYSRyrGsoQ5qPwc8ycvLZw== +"@types/debug@^4.1.6": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" + integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== dependencies: - "@babel/runtime" "^7.5.5" - "@emotion/cache" "^10.0.27" - "@emotion/css" "^10.0.27" - "@emotion/serialize" "^0.11.15" - "@emotion/sheet" "0.9.4" - "@emotion/utils" "0.11.3" - -"@emotion/css@^10.0.27", "@emotion/css@^10.0.9": - version "10.0.27" - resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c" - integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw== - dependencies: - "@emotion/serialize" "^0.11.15" - "@emotion/utils" "0.11.3" - babel-plugin-emotion "^10.0.27" - -"@emotion/hash@0.7.4": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.4.tgz#f14932887422c9056b15a8d222a9074a7dfa2831" - integrity sha512-fxfMSBMX3tlIbKUdtGKxqB1fyrH6gVrX39Gsv3y8lRYKUqlgDt3UMqQyGnR1bQMa2B8aGnhLZokZgg8vT0Le+A== - -"@emotion/memoize@0.7.4": - version "0.7.4" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" - integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== - -"@emotion/serialize@^0.11.15": - version "0.11.15" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.15.tgz#9a0f5873fb458d87d4f23e034413c12ed60a705a" - integrity sha512-YE+qnrmGwyR+XB5j7Bi+0GT1JWsdcjM/d4POu+TXkcnrRs4RFCCsi3d/Ebf+wSStHqAlTT2+dfd+b9N9EO2KBg== - dependencies: - "@emotion/hash" "0.7.4" - "@emotion/memoize" "0.7.4" - "@emotion/unitless" "0.7.5" - "@emotion/utils" "0.11.3" - csstype "^2.5.7" - -"@emotion/sheet@0.9.4": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5" - integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA== - -"@emotion/stylis@0.8.5": - version "0.8.5" - resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" - integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== - -"@emotion/unitless@0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" - integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== - -"@emotion/utils@0.11.3": - version "0.11.3" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924" - integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw== - -"@emotion/weak-memoize@0.2.5": - version "0.2.5" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" - integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== - -"@jest/console@^24.7.1", "@jest/console@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" - integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== - dependencies: - "@jest/source-map" "^24.9.0" - chalk "^2.0.1" - slash "^2.0.0" - -"@jest/core@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" - integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== - dependencies: - "@jest/console" "^24.7.1" - "@jest/reporters" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-changed-files "^24.9.0" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-resolve-dependencies "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - jest-watcher "^24.9.0" - micromatch "^3.1.10" - p-each-series "^1.0.0" - realpath-native "^1.1.0" - rimraf "^2.5.4" - slash "^2.0.0" - strip-ansi "^5.0.0" - -"@jest/environment@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" - integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== - dependencies: - "@jest/fake-timers" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - -"@jest/fake-timers@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" - integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== - dependencies: - "@jest/types" "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - -"@jest/reporters@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" - integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - exit "^0.1.2" - glob "^7.1.2" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-report "^2.0.4" - istanbul-lib-source-maps "^3.0.1" - istanbul-reports "^2.2.6" - jest-haste-map "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" - node-notifier "^5.4.2" - slash "^2.0.0" - source-map "^0.6.0" - string-length "^2.0.0" + "@types/ms" "*" -"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" - integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== dependencies: - callsites "^3.0.0" - graceful-fs "^4.1.15" - source-map "^0.6.0" + "@types/eslint" "*" + "@types/estree" "*" -"@jest/test-result@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" - integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== +"@types/eslint@*": + version "8.37.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.37.0.tgz#29cebc6c2a3ac7fea7113207bf5a828fdf4d7ef1" + integrity sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ== dependencies: - "@jest/console" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/istanbul-lib-coverage" "^2.0.0" + "@types/estree" "*" + "@types/json-schema" "*" -"@jest/test-sequencer@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" - integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== - dependencies: - "@jest/test-result" "^24.9.0" - jest-haste-map "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" - -"@jest/transform@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" - integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^24.9.0" - babel-plugin-istanbul "^5.1.0" - chalk "^2.0.1" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.1.15" - jest-haste-map "^24.9.0" - jest-regex-util "^24.9.0" - jest-util "^24.9.0" - micromatch "^3.1.10" - pirates "^4.0.1" - realpath-native "^1.1.0" - slash "^2.0.0" - source-map "^0.6.1" - write-file-atomic "2.4.1" +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== -"@jest/types@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" - integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== +"@types/express-serve-static-core@^4.17.33": + version "4.17.35" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz#c95dd4424f0d32e525d23812aa8ab8e4d3906c4f" + integrity sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg== dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^13.0.0" - -"@sindresorhus/is@^0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" - integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" -"@types/babel__core@^7.1.0": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" - integrity sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA== +"@types/express@^4.17.17": + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" -"@types/babel__generator@*": - version "7.6.1" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" - integrity sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew== +"@types/fs-extra@^9.0.11": + version "9.0.13" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45" + integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== dependencies: - "@babel/types" "^7.0.0" + "@types/node" "*" -"@types/babel__template@*": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" - integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== +"@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@types/minimatch" "*" + "@types/node" "*" -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.0.8" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.8.tgz#479a4ee3e291a403a1096106013ec22cf9b64012" - integrity sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw== +"@types/graceful-fs@^4.1.3": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: - "@babel/types" "^7.3.0" + "@types/node" "*" -"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1": +"@types/hoist-non-react-statics@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== @@ -1050,278 +1026,351 @@ "@types/react" "*" hoist-non-react-statics "^3.3.0" -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" - integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== "@types/istanbul-lib-report@*": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c" - integrity sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg== + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== dependencies: "@types/istanbul-lib-coverage" "*" -"@types/istanbul-reports@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" - integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== dependencies: - "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/jest@^24.0.23": - version "24.0.25" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.25.tgz#2aba377824ce040114aa906ad2cac2c85351360f" - integrity sha512-hnP1WpjN4KbGEK4dLayul6lgtys6FPz0UfxMeMQCv0M+sTnzN3ConfiO72jHgLxl119guHgI8gLqDOrRLsyp2g== +"@types/jest@^29.5.1": + version "29.5.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.1.tgz#83c818aa9a87da27d6da85d3378e5a34d2f31a47" + integrity sha512-tEuVcHrpaixS36w7hpsfLBLpjtMRJUE09/MHXn923LOVojDwyC14cWcfc0rDs0VEfUyYmt/+iX1kxxp+gZMcaQ== dependencies: - jest-diff "^24.3.0" + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/json-schema@*", "@types/json-schema@^7.0.8": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/long@^4.0.0": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/minimatch@*": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + +"@types/ms@*": + version "0.7.31" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + +"@types/node@*", "@types/node@>=10.0.0": + version "20.1.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.1.5.tgz#e94b604c67fc408f215fcbf3bd84d4743bf7f710" + integrity sha512-IvGD1CD/nego63ySR7vrAKEX3AJTcmrAN2kn+/sDNLi1Ff5kBzDeEdqWDplK+0HAEoLYej137Sk0cUU8OLOlMg== + +"@types/node@^14.6.2": + version "14.18.47" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.47.tgz#89a56b05804d136cb99bf2f823bb00814a889aae" + integrity sha512-OuJi8bIng4wYHHA3YpKauL58dZrPxro3d0tabPHyiNF8rKfGKuVfr83oFlPLmKri1cX+Z3cJP39GXmnqkP11Gw== + +"@types/node@^18.16.0": + version "18.16.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.10.tgz#9b16d918f4f6fec6cae4af34283a91d555b81519" + integrity sha512-sMo3EngB6QkMBlB9rBe1lFdKSLqljyWPPWv6/FzSxh/IDlyVWSzE9RiF4eAuerQHybrWdqBgAGb03PM89qOasA== "@types/node@^7.0.4": - version "7.10.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.10.9.tgz#4343e3b009f8cf5e1ed685e36097b74b4101e880" - integrity sha512-usSpgoUsRtO5xNV5YEPU8PPnHisFx8u0rokj1BPVn/hDF7zwUDzVLiuKZM38B7z8V2111Fj6kd4rGtQFUZpNOw== + version "7.10.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-7.10.14.tgz#06fa7319b8131b969a8da4a14c487e6f28abacf7" + integrity sha512-29GS75BE8asnTno3yB6ubOJOO0FboExEqNJy4bpz0GSmW/8wPTNL4h9h63c6s1uTrOopCmJYe/4yJLh5r92ZUA== "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/plist@^3.0.1": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01" + integrity sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw== + dependencies: + "@types/node" "*" + xmlbuilder ">=11.0.1" + +"@types/prettier@^2.1.5": + version "2.7.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" + integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== + "@types/prop-types@*": - version "15.7.3" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" - integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + version "15.7.5" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/rc-slider@^8.6.5": - version "8.6.5" - resolved "https://registry.yarnpkg.com/@types/rc-slider/-/rc-slider-8.6.5.tgz#5032e5a4e4074588068d4b149f9e80a5ae80d8e3" - integrity sha512-cz5xqjsN4OtqoX0gMG5KheFUV/4DwmzpSXJdLyHQXp2xwfPyPggh7nLy9nwKXQhXLnimOH3EXz9AAlsA8UGkLg== +"@types/react-dom@^18.2.4": + version "18.2.4" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.4.tgz#13f25bfbf4e404d26f62ac6e406591451acba9e0" + integrity sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw== dependencies: - "@types/rc-tooltip" "*" "@types/react" "*" -"@types/rc-tooltip@*": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@types/rc-tooltip/-/rc-tooltip-3.7.2.tgz#bbf35284cc1adf6fb61cc49262fd4199ebcc7bff" - integrity sha512-N1SJZlYzMxU96ACxzdBfWfG8o4oQpDRjuWrenIrvzAYFUnMscSZVx1LU7zmHO2aOumLz7G0odNxREt3BrE1WHg== +"@types/react-test-renderer@^18.0.0": + version "18.0.0" + resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz#7b7f69ca98821ea5501b21ba24ea7b6139da2243" + integrity sha512-C7/5FBJ3g3sqUahguGi03O79b8afNeSD6T8/GU50oQrJCU0bVCCGQHaGKUbg2Ce8VQEEqTw8/HiS6lXHHdgkdQ== dependencies: "@types/react" "*" -"@types/react-dom@*": - version "16.9.4" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.4.tgz#0b58df09a60961dcb77f62d4f1832427513420df" - integrity sha512-fya9xteU/n90tda0s+FtN5Ym4tbgxpq/hb/Af24dvs6uYnYn+fspaxw5USlw0R8apDNwxsqumdRoCoKitckQqw== +"@types/react-transition-group@^4.4.0": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.6.tgz#18187bcda5281f8e10dfc48f0943e2fdf4f75e2e" + integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew== dependencies: "@types/react" "*" -"@types/react-redux@^7.1.4": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.5.tgz#c7a528d538969250347aa53c52241051cf886bd3" - integrity sha512-ZoNGQMDxh5ENY7PzU7MVonxDzS1l/EWiy8nUhDqxFqUZn4ovboCyvk4Djf68x6COb7vhGTKjyjxHxtFdAA5sUA== +"@types/react@*": + version "18.2.6" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.6.tgz#5cd53ee0d30ffc193b159d3516c8c8ad2f19d571" + integrity sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA== dependencies: - "@types/hoist-non-react-statics" "^3.3.0" - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - redux "^4.0.0" + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" -"@types/react-select@^3.0.4": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-3.0.8.tgz#b824a12d438dd493c30ffff49a805f797602a837" - integrity sha512-0763TXYZc8bTiHM+DUnWoy9Rg5mk6PxYWBrEe6Fkjgc0Kv0r1RqjZk9/BrK4wdM0RNjYjixlFPnUhOJb76sMGg== +"@types/safer-buffer@2.1.0", "@types/safer-buffer@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/safer-buffer/-/safer-buffer-2.1.0.tgz#8c498815fe00af8f8b23d63eb3fd6fae6ae2ab7a" + integrity sha512-04WlrCdOLy1Ejpwc3A7qyZzsH6uqeWoH+XO80V8S8NRubGg+E4FMMM3VAS6jZZ8w+dXki1/5FI5upmMDQlaQsQ== dependencies: - "@types/react" "*" - "@types/react-dom" "*" - "@types/react-transition-group" "*" + "@types/node" "*" + +"@types/scheduler@*": + version "0.16.3" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== -"@types/react-test-renderer@^16.9.1": - version "16.9.1" - resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-16.9.1.tgz#9d432c46c515ebe50c45fa92c6fb5acdc22e39c4" - integrity sha512-nCXQokZN1jp+QkoDNmDZwoWpKY8HDczqevIDO4Uv9/s9rbGPbSpy8Uaxa5ixHKkcm/Wt0Y9C3wCxZivh4Al+rQ== +"@types/send@*": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.1.tgz#ed4932b8a2a805f1fe362a70f4e62d0ac994e301" + integrity sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q== dependencies: - "@types/react" "*" + "@types/mime" "^1" + "@types/node" "*" -"@types/react-transition-group@*": - version "4.2.3" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.2.3.tgz#4924133f7268694058e415bf7aea2d4c21131470" - integrity sha512-Hk8jiuT7iLOHrcjKP/ZVSyCNXK73wJAUz60xm0mVhiRujrdiI++j4duLiL282VGxwAgxetHQFfqA29LgEeSkFA== +"@types/serve-static@*": + version "1.15.1" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.1.tgz#86b1753f0be4f9a1bee68d459fcda5be4ea52b5d" + integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== dependencies: - "@types/react" "*" + "@types/mime" "*" + "@types/node" "*" -"@types/react@*": - version "16.9.17" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.17.tgz#58f0cc0e9ec2425d1441dd7b623421a867aa253e" - integrity sha512-UP27In4fp4sWF5JgyV6pwVPAQM83Fj76JOcg02X5BZcpSu5Wx+fP9RMqc2v0ssBoQIFvD5JdKY41gjJJKmw6Bg== +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/use-sync-external-store@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" + integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== + +"@types/verror@^1.10.3": + version "1.10.6" + resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.6.tgz#3e600c62d210c5826460858f84bcbb65805460bb" + integrity sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ== + +"@types/webmidi@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@types/webmidi/-/webmidi-2.0.7.tgz#db6bc2e5fbf2ece44265b0a4fafde6573acd5210" + integrity sha512-BMVefNAum/swSmQJdTbRWBuDPeWT7fHAZEzmtY6eBl1ObvkWVzh39VvAFC8v9n7Y5XoOpWmeYzyUUVfmpq3ggQ== + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^17.0.1", "@types/yargs@^17.0.8": + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== dependencies: - "@types/prop-types" "*" - csstype "^2.2.0" + "@types/yargs-parser" "*" + +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@types/socket.io-client@^1.4.32": - version "1.4.32" - resolved "https://registry.yarnpkg.com/@types/socket.io-client/-/socket.io-client-1.4.32.tgz#988a65a0386c274b1c22a55377fab6a30789ac14" - integrity sha512-Vs55Kq8F+OWvy1RLA31rT+cAyemzgm0EWNeax6BWF8H7QiiOYMJIdcwSDdm5LVgfEkoepsWkS+40+WNb7BUMbg== +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== -"@types/stack-utils@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" - integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" -"@types/yargs-parser@*": - version "13.1.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" - integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@types/yargs@^13.0.0": - version "13.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.4.tgz#53d231cebe1a540e7e13727fc1f0d13ad4a9ba3b" - integrity sha512-Ke1WmBbIkVM8bpvsNEcGgQM70XcEh/nbpxQhW7FhrsbCsXSY9BmLB1+LHtD7r9zrsOcFlLiF+a/UeJsdfw3C5A== +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== dependencies: - "@types/yargs-parser" "*" + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "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/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@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@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - "@xtuc/long" "4.2.2" +"@webpack-cli/configtest@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.0.tgz#b59b33377b1b896a9a7357cfc643b39c1524b1e6" + integrity sha512-K/vuv72vpfSEZoo5KIU0a2FsEoYdW0DUMtMpB5X3LlUwshetMZRZRxB7sCsVji/lFaSxtQQ3aM9O4eMolXkU9w== + +"@webpack-cli/info@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.1.tgz#eed745799c910d20081e06e5177c2b2569f166c0" + integrity sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA== + +"@webpack-cli/serve@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.4.tgz#3982ee6f8b42845437fc4d391e93ac5d9da52f0f" + integrity sha512-0xRgjgDLdz6G7+vvDLlaRpFatJaJ69uTalZLRSMX5B3VUrDmXcrVA3+6fXXQgmYz7bY9AAgs348XQdmtLsK41A== + +"@xmldom/xmldom@^0.8.2": + version "0.8.7" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.7.tgz#8b1e39c547013941974d83ad5e9cf5042071a9a0" + integrity sha512-sI1Ly2cODlWStkINzqGrZ8K6n+MTSbAeQnAipGyL+KZCXuHaRlj2gyyy8B/9MvsFFqN7XHryQnB2QwhzvJXovg== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -1333,134 +1382,181 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -JSONStream@^1.0.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -abab@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" - integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== - -accepts@~1.3.4, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-globals@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" - -acorn-walk@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== - -acorn@^5.5.3: - version "5.7.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" - integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + mime-types "~2.1.34" + negotiator "0.6.3" -acorn@^6.0.1, acorn@^6.2.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" - integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== +acorn-import-assertions@^1.7.6: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== -add-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" - integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -after@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" - integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= +acorn@^8.5.0, acorn@^8.7.1: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== +ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.5.5: - version "6.10.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== +ajv@^6.10.0, ajv@^6.12.0, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: - fast-deep-equal "^2.0.1" + 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-colors@3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" - integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== +alawmulaw@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/alawmulaw/-/alawmulaw-5.0.2.tgz#885a914933e3f3bc0bdd67534af669a20f17d4aa" + integrity sha512-W3bWBB7MwTNGALlAKbOxe+tMNW9DpqGsv1V1idGPzctnBH++eS+Dx3UuucHNe5nk38WvAuy0sgMAbS5idHCArw== -ansi-escapes@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^4.0.0, ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" + color-convert "^2.0.1" -aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +ansi-styles@^6.0.0, ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== -archy@1.0.0: +ansicolors@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" + integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +app-builder-bin@3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.7.1.tgz#cb0825c5e12efc85b196ac3ed9c89f076c61040e" + integrity sha512-ql93vEUq6WsstGXD+SBLSIQw6SNnhbDEM0swzgugytMxLp3rT24Ag/jcC80ZHxiPRTdew1niuR7P3/FCrDqIjw== + +app-builder-lib@22.14.5: + version "22.14.5" + resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.14.5.tgz#a61a50b132b858e98fdc70b6b88994ae99b4f96d" + integrity sha512-k3VwKP4kpsnUaXoUkm1s4zaSHPHIMFnN4kPMU9yXaKmE1LfHHqBaEah5bXeTAX5V/BC41wFdg8CF5vOjvgy8Rg== + dependencies: + "7zip-bin" "~5.1.1" + "@develar/schema-utils" "~2.6.5" + "@electron/universal" "1.0.5" + "@malept/flatpak-bundler" "^0.4.0" + async-exit-hook "^2.0.1" + bluebird-lst "^1.0.9" + builder-util "22.14.5" + builder-util-runtime "8.9.1" + chromium-pickle-js "^0.2.0" + debug "^4.3.2" + ejs "^3.1.6" + electron-osx-sign "^0.5.0" + electron-publish "22.14.5" + form-data "^4.0.0" + fs-extra "^10.0.0" + hosted-git-info "^4.0.2" + is-ci "^3.0.0" + isbinaryfile "^4.0.8" + js-yaml "^4.1.0" + lazy-val "^1.0.5" + minimatch "^3.0.4" + read-config-file "6.2.0" + sanitize-filename "^1.6.3" + semver "^7.3.5" + temp-file "^3.4.0" + +app-module-path@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5" + integrity sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ== + +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +archy@1.0.0, archy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== -arg@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.2.tgz#e70c90579e02c63d80e3ad4e31d8bfdb8bd50064" - integrity sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg== +are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" argparse@^1.0.7: version "1.0.10" @@ -1469,345 +1565,288 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -array-find-index@^1.0.1: +array-find-index@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + integrity sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw== array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-ify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -arraybuffer.slice@~0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" - integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== -asap@^2.0.0, asap@~2.0.6: +asap@^2.0.0, asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== -asn1.js@^4.0.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== +asar@^3.0.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/asar/-/asar-3.2.0.tgz#e6edb5edd6f627ebef04db62f771c61bea9c1221" + integrity sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg== dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" + chromium-pickle-js "^0.2.0" + commander "^5.0.0" + glob "^7.1.6" + minimatch "^3.0.4" + optionalDependencies: + "@types/glob" "^7.1.1" asn1@evs-broadcast/node-asn1: - version "0.5.1" - resolved "https://codeload.github.com/evs-broadcast/node-asn1/tar.gz/2fc158464a92e1465523f108295abd54e7ce86db" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + version "0.5.4" + resolved "https://codeload.github.com/evs-broadcast/node-asn1/tar.gz/0146823069e479e90595480dc90c72cafa161ba1" dependencies: + "@types/safer-buffer" "^2.1.0" safer-buffer "~2.1.0" -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assert@^1.1.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" - integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== - dependencies: - object-assign "^4.1.1" - util "0.10.3" - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +assert-never@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" + integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== -astral-regex@^1.0.0: +assert-plus@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -async-limiter@^1.0.0, async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +async-exit-hook@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3" + integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw== -async@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== +async@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== dependencies: lodash "^4.17.14" -async@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" - integrity sha1-+PwEyjoTeErenhZBr5hXjPvWR6k= +async@^3.2.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -aws4@^1.8.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c" - integrity sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A== - -babel-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" - integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== - dependencies: - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/babel__core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.9.0" - chalk "^2.4.2" - slash "^2.0.0" - -babel-loader@^8.0.6: - version "8.0.6" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" - integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw== - dependencies: - find-cache-dir "^2.0.0" - loader-utils "^1.0.2" - mkdirp "^0.5.1" - pify "^4.0.1" - -babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-emotion@^10.0.27: - version "10.0.27" - resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.27.tgz#59001cf5de847c1d61f2079cd906a90a00d3184f" - integrity sha512-SUNYcT4FqhOqvwv0z1oeYhqgheU8qrceLojuHyX17ngo7WtWqN5I9l3IGHzf21Xraj465CVzF4IvOlAF+3ed0A== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@emotion/hash" "0.7.4" - "@emotion/memoize" "0.7.4" - "@emotion/serialize" "^0.11.15" - babel-plugin-macros "^2.0.0" - babel-plugin-syntax-jsx "^6.18.0" - convert-source-map "^1.5.0" - escape-string-regexp "^1.0.5" - find-root "^1.1.0" - source-map "^0.5.7" +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -babel-plugin-istanbul@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" - integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== +atem-connection@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/atem-connection/-/atem-connection-3.2.0.tgz#139b6f935a774d40e2ec337746777d3e87ca0c54" + integrity sha512-9kn/uC6DQIIGSg+n+M84lXm9nPOXkvKHN3/TFnsAev/xVeFSSy5OgvfqkcUF3/+HxJNeuUc4bj+ezEVn/AKbMA== + dependencies: + "@julusian/freetype2" "^1.1.0" + debug "^4.3.4" + eventemitter3 "^4.0.7" + exit-hook "^2.2.1" + nanotimer "^0.3.15" + p-lazy "^3.1.0" + p-queue "^6.6.2" + threadedclass "^1.1.1" + tslib "^2.3.1" + wavefile "^8.4.4" + +axios@^0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== + dependencies: + follow-redirects "^1.14.9" + form-data "^4.0.0" + +babel-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.5.0.tgz#3fe3ddb109198e78b1c88f9ebdecd5e4fc2f50a5" + integrity sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q== + dependencies: + "@jest/transform" "^29.5.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.5.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - find-up "^3.0.0" - istanbul-lib-instrument "^3.3.0" - test-exclude "^5.2.3" - -babel-plugin-jest-hoist@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" - integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== - dependencies: + "@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@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" + integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" -babel-plugin-macros@^2.0.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" - integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== - dependencies: - "@babel/runtime" "^7.7.2" - cosmiconfig "^6.0.0" - resolve "^1.12.0" - -babel-plugin-syntax-jsx@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= - -babel-preset-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" - integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== +babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.9.0" + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" -backo2@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" - integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" + integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== + dependencies: + babel-plugin-jest-hoist "^29.5.0" + babel-preset-current-node-syntax "^1.0.0" + +babel-walk@3.0.0-canary-5: + version "3.0.0-canary-5" + resolved "https://registry.yarnpkg.com/babel-walk/-/babel-walk-3.0.0-canary-5.tgz#f66ecd7298357aee44955f235a6ef54219104b11" + integrity sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw== + dependencies: + "@babel/types" "^7.9.6" balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-arraybuffer@0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" - integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= +base64-arraybuffer-es6@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.3.1.tgz#fdf0e382f4e2f56caf881f48ee0ce01ae79afe48" + integrity sha512-TrhBheudYaff9adiTAqjSScjvtmClQ4vF9l4cqkPNkVsA11m4/NRdH4LkZ/tAMmpzzwfI20BXnJ/PTtafECCNA== -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== +base64-js@^1.3.1, base64-js@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -base64id@2.0.0: +base64id@2.0.0, base64id@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -better-assert@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" - integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= - dependencies: - callsite "1.0.0" - -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" - integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +bitdepth@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/bitdepth/-/bitdepth-7.0.2.tgz#d9290de0e4b44ce5fc0c29f813c8f49fbdfa2eeb" + integrity sha512-Ed11TL4IIWyUEoQTfkbRBDCgDNurxYzFgmk30ZU6SgNCsysoEx7UMm+g7SDFHxA2lhLbWyjV8T1ab3z0BtYOAw== -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== +bluebird-lst@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/bluebird-lst/-/bluebird-lst-1.0.9.tgz#a64a0e4365658b9ab5fe875eb9dfb694189bb41c" + integrity sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw== dependencies: - file-uri-to-path "1.0.0" - -blob@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" - integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + bluebird "^3.5.5" -bluebird@^3.5.5: +bluebird@^3.5.0, bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== - -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== dependencies: - bytes "3.1.0" + bytes "3.1.2" content-type "~1.0.4" debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" + 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.1" + type-is "~1.6.18" + unpipe "1.0.0" + +body-parser@^1.20.1: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + 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.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" -boolbase@~1.0.0: +boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +boolean@^3.0.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b" + integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw== + +boxen@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" brace-expansion@^1.1.7: version "1.1.11" @@ -1817,118 +1856,29 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" + balanced-match "^1.0.0" -braces@^3.0.1: +braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" -brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browser-process-hrtime@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" - integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== - -browser-resolve@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" - integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== - dependencies: - resolve "1.1.7" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= - dependencies: - bn.js "^4.1.0" - randombytes "^2.0.1" - -browserify-sign@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" - integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= - dependencies: - bn.js "^4.1.1" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.2" - elliptic "^6.0.0" - inherits "^2.0.1" - parse-asn1 "^5.0.0" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - -browserslist@^4.6.0, browserslist@^4.8.3: - version "4.8.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.3.tgz#65802fcd77177c878e015f0e3189f2c4f627ba44" - integrity sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg== +browserslist@^4.14.5, browserslist@^4.21.3: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== dependencies: - caniuse-lite "^1.0.30001017" - electron-to-chromium "^1.3.322" - node-releases "^1.1.44" + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" bs-logger@0.x: version "0.2.6" @@ -1944,173 +1894,166 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-from@1.x, buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== -buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +buffer-equal@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + integrity sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ== -cacache@^12.0.2: - version "12.0.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cacheable-request@^2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" - integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= - dependencies: - clone-response "1.0.2" - get-stream "3.0.0" - http-cache-semantics "3.8.1" - keyv "3.0.0" - lowercase-keys "1.0.0" - normalize-url "2.0.1" - responselike "1.0.2" - -callsite@1.0.0: +buffer-fill@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" - integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -camel-case@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= +buffer@^5.1.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" + base64-js "^1.3.1" + ieee754 "^1.1.13" -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= +builder-util-runtime@8.9.1: + version "8.9.1" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.9.1.tgz#25f066b3fbc20b3e6236a9b956b1ebb0e33ff66a" + integrity sha512-c8a8J3wK6BIVLW7ls+7TRK9igspTbzWmUqxFbgK0m40Ggm6efUbxtWVCGIjc+dtchyr5qAMAUL6iEGRdS/6vwg== dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" + debug "^4.3.2" + sax "^1.2.4" -camelcase-keys@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" - integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= +builder-util@22.14.5: + version "22.14.5" + resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.14.5.tgz#42a18608d2a566c0846e91266464776c8bfb0cc9" + integrity sha512-zqIHDFJwmA7jV7SC9aI+33MWwT2mWoijH+Ol9IntNAwuuRXoS+7XeJwnhLBXOhcDBzXT4kDzHnRk4JKeaygEYA== + dependencies: + "7zip-bin" "~5.1.1" + "@types/debug" "^4.1.6" + "@types/fs-extra" "^9.0.11" + app-builder-bin "3.7.1" + bluebird-lst "^1.0.9" + builder-util-runtime "8.9.1" + chalk "^4.1.1" + cross-spawn "^7.0.3" + debug "^4.3.2" + fs-extra "^10.0.0" + is-ci "^3.0.0" + js-yaml "^4.1.0" + source-map-support "^0.5.19" + stat-mode "^1.0.0" + temp-file "^3.4.0" + +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== + +byte-data@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/byte-data/-/byte-data-16.0.3.tgz#8abb3e212c9b026790a28c2d6c22fdc0515fd49d" + integrity sha512-IzV3mzv8OnnzPdb9CoESQr2ikPX/gkHUesRu+vff9XB7KwMxyflPDewtPFWXPvF+Xukl52ceor2IRLbnQZf3PQ== dependencies: - camelcase "^4.1.0" - map-obj "^2.0.0" - quick-lru "^1.0.0" + endianness "^8.0.2" + ieee754-buffer "^0.2.1" + twos-complement-buffer "0.0.1" + uint-buffer "^0.1.0" + utf8-buffer "^0.2.0" -camelcase@^2.0.0, camelcase@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0, callsites@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" -camelcase@^5.0.0, camelcase@^5.3.1: +camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30001017: - version "1.0.30001019" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001019.tgz#857e3fccaad2b2feb3f1f6d8a8f62d747ea648e1" - integrity sha512-6ljkLtF1KM5fQ+5ZN0wuyVvvebJxgJPTmScOMaFuQN2QuOzvRJnWSKfzQskQU5IOU4Gap3zasYPIinzwUjoj/g== - -capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== - dependencies: - rsvp "^4.8.4" +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +caniuse-lite@^1.0.30001449: + version "1.0.30001487" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001487.tgz#d882d1a34d89c11aea53b8cdc791931bdab5fe1b" + integrity sha512-83564Z3yWGqXsh2vaH/mhXfEM0wX+NlBCm1jYHOb97TrTWJEmPTccZgeLTPBUUb0PNVo+oomb7wkimZBIERClA== -casparcg-connection@^4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/casparcg-connection/-/casparcg-connection-4.9.0.tgz#1fb19e091ff785d312f52ed065c4077dbe55196c" - integrity sha512-K2c38+6RB4Agb116q4WapmZQSDAz95nlijgndpG2sYEX9lxHRJmBrJ+uysxrgJT/dXYlPGrEx++pEqwRpXPtLA== +casparcg-connection@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/casparcg-connection/-/casparcg-connection-5.1.0.tgz#6ea23c2895b5a28e2cd362a0ab0cd19c6ce68805" + integrity sha512-efYJG3jO2HPNJ0RUCvwmVlesXSbPfTxSoMuiUoOO86C7H5mTte4O8jGa6it7YShyBr8NTpUfPqiPEb7bKTAW3w== dependencies: highland "^3.0.0-beta.6" xml2js "^0.4.19" xmlbuilder "^9.0.7" -chai@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" - integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - pathval "^1.1.0" - type-detect "^4.0.5" +chalk@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" + integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.2: +chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2119,249 +2062,255 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -check-error@^1.0.2: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -chokidar@^2.0.2: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -chownr@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" - integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== +character-parser@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" + integrity sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw== + dependencies: + is-regex "^1.0.3" chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +chromium-pickle-js@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" + integrity sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw== ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== +ci-info@^3.2.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + +classnames@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== + +clean-css@^5.2.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" + integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" + source-map "~0.6.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" + restore-cursor "^3.1.0" -classnames@^2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" - integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" -clean-css@4.2.x: - version "4.2.1" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" - integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== dependencies: - source-map "~0.6.0" + slice-ansi "^5.0.0" + string-width "^5.0.0" -cliui@^3.0.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" -clone-response@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== dependencies: mimic-response "^1.0.0" +clsx@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + +cluster-key-slot@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" + integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== -color-convert@^1.9.0, color-convert@^1.9.1: +color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@^1.0.0: +color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" - integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== -colornames@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" - integrity sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y= +colorette@^2.0.14, colorette@^2.0.19: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== -colors@1.0.x: +colors@1.0.3, colors@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" - integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= - -colors@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + integrity sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw== -colorspace@1.1.x: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" - integrity sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ== - dependencies: - color "3.0.x" - text-hex "1.0.x" - -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" -commander@2.17.x: - version "2.17.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" - integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== +commander@2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + integrity sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A== dependencies: graceful-readlink ">= 1.0.0" -commander@^2.20.0, commander@~2.20.3: +commander@^10.0.0, commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@~2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -compare-func@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" - integrity sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg= - dependencies: - array-ify "^1.0.0" - dot-prop "^3.0.0" +commander@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -compare-versions@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.0.0.tgz#92da44cf19ea53fff6c6e8d4e88221d4e155d672" - integrity sha1-ktpEzxnqU//2xujU6IIh1OFV1nI= +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== -component-bind@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" - integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= +compare-version@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" + integrity sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A== -component-emitter@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= +compare-versions@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" + integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" -component-inherit@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" - integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concat-stream@^1.5.0: +concat-stream@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -2371,1206 +2320,915 @@ concat-stream@^1.5.0: readable-stream "^2.2.2" typedarray "^0.0.6" -concat-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" - integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.0.2" - typedarray "^0.0.6" - -console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.2" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -conventional-changelog-angular@^5.0.5: - version "5.0.6" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.6.tgz#269540c624553aded809c29a3508fdc2b544c059" - integrity sha512-QDEmLa+7qdhVIv8sFZfVxU1VSyVvnXPsxq8Vam49mKUcO1Z8VTLEJk9uI21uiJUsnmm0I4Hrsdc9TgkOQo9WSA== - dependencies: - compare-func "^1.3.1" - q "^1.5.1" - -conventional-changelog-atom@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/conventional-changelog-atom/-/conventional-changelog-atom-2.0.3.tgz#3bd14280aa09fe3ec49a0e8fe97b5002db02aad4" - integrity sha512-szZe2ut97qNO6vCCMkm1I/tWu6ol4Rr8a9Lx0y/VlpDnpY0PNp+oGpFgU55lplhx+I3Lro9Iv4/gRj0knfgjzg== - dependencies: - q "^1.5.1" - -conventional-changelog-codemirror@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.3.tgz#ebc088154684f8f5171446b8d546ba6b460d46f2" - integrity sha512-t2afackdgFV2yBdHhWPqrKbpaQeVnz2hSJKdWqjasPo5EpIB6TBL0er3cOP1mnGQmuzk9JSvimNSuqjWGDtU5Q== +concurrently@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-8.0.1.tgz#80c0591920a9fa3e68ba0dd8aa6eac8487eb904c" + integrity sha512-Sh8bGQMEL0TAmAm2meAXMjcASHZa7V0xXQVDBLknCPa9TPtkY9yYs+0cnGGgfdkW0SV1Mlg+hVGfXcoI8d3MJA== + dependencies: + chalk "^4.1.2" + date-fns "^2.29.3" + lodash "^4.17.21" + rxjs "^7.8.0" + shell-quote "^1.8.0" + spawn-command "0.0.2-1" + supports-color "^8.1.1" + tree-kill "^1.2.2" + yargs "^17.7.1" + +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== dependencies: - q "^1.5.1" - -conventional-changelog-config-spec@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz#874a635287ef8b581fd8558532bf655d4fb59f2d" - integrity sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ== + ini "^1.3.4" + proto-list "~1.2.1" -conventional-changelog-conventionalcommits@^4.2.1: - version "4.2.3" - resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.2.3.tgz#22855b32d57d0328951c1c2dc01b172a5f24ea37" - integrity sha512-atGa+R4vvEhb8N/8v3IoW59gCBJeeFiX6uIbPu876ENAmkMwsenyn0R21kdDHJFLQdy6zW4J6b4xN8KI3b9oww== +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== dependencies: - compare-func "^1.3.1" - lodash "^4.17.15" - q "^1.5.1" - -conventional-changelog-core@^4.0.2: - version "4.1.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-4.1.4.tgz#39be27fca6ef20a0f998d7a3a1e97cfa8a055cb6" - integrity sha512-LO58ZbEpp1Ul+y/vOI8rJRsWkovsYkCFbOCVgi6UnVfU8WC0F8K8VQQwaBZWWUpb6JvEiN4GBR5baRP2txZ+Vg== - dependencies: - add-stream "^1.0.0" - conventional-changelog-writer "^4.0.11" - conventional-commits-parser "^3.0.8" - dateformat "^3.0.0" - get-pkg-repo "^1.0.0" - git-raw-commits "2.0.0" - git-remote-origin-url "^2.0.0" - git-semver-tags "^3.0.1" - lodash "^4.17.15" - normalize-package-data "^2.3.5" - q "^1.5.1" - read-pkg "^3.0.0" - read-pkg-up "^3.0.0" - through2 "^3.0.0" + dot-prop "^5.2.0" + graceful-fs "^4.1.2" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" -conventional-changelog-ember@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-2.0.4.tgz#c29b78e4af7825cbecb6c3fd6086ca5c09471ac1" - integrity sha512-q1u73sO9uCnxN4TSw8xu6MRU8Y1h9kpwtcdJuNRwu/LSKI1IE/iuNSH5eQ6aLlQ3HTyrIpTfUuVybW4W0F17rA== - dependencies: - q "^1.5.1" +connect-redis@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/connect-redis/-/connect-redis-6.1.3.tgz#0a83c953f9ece45ae37d304a8e8d1c3c6a60b4b9" + integrity sha512-aaNluLlAn/3JPxRwdzw7lhvEoU6Enb+d83xnokUNhC9dktqBoawKWL+WuxinxvBLTz6q9vReTnUDnUslaz74aw== -conventional-changelog-eslint@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.4.tgz#8f4736a23e0cd97e890e76fccc287db2f205f2ff" - integrity sha512-CPwTUENzhLGl3auunrJxiIEWncAGaby7gOFCdj2gslIuOFJ0KPJVOUhRz4Da/I53sdo/7UncUJkiLg94jEsjxg== - dependencies: - q "^1.5.1" +console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== -conventional-changelog-express@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-express/-/conventional-changelog-express-2.0.1.tgz#fea2231d99a5381b4e6badb0c1c40a41fcacb755" - integrity sha512-G6uCuCaQhLxdb4eEfAIHpcfcJ2+ao3hJkbLrw/jSK/eROeNfnxCJasaWdDAfFkxsbpzvQT4W01iSynU3OoPLIw== +constantinople@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151" + integrity sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw== dependencies: - q "^1.5.1" + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.1" -conventional-changelog-jquery@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.6.tgz#460236ad8fb1d29ff932a14fe4e3a45379b63c5e" - integrity sha512-gHAABCXUNA/HjnZEm+vxAfFPJkgtrZvCDIlCKfdPVXtCIo/Q0lN5VKpx8aR5p8KdVRQFF3OuTlvv5kv6iPuRqA== +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: - q "^1.5.1" + safe-buffer "5.2.1" -conventional-changelog-jshint@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.3.tgz#ef6e2caf2ee6ffdfda78fcdf7ce87cf6c512d728" - integrity sha512-Pc2PnMPcez634ckzr4EOWviwRSpZcURaK7bjyD9oK6N5fsC/a+3G7LW5m/JpcHPhA9ZxsfIbm7uqZ3ZDGsQ/sw== - dependencies: - compare-func "^1.3.1" - q "^1.5.1" +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -conventional-changelog-preset-loader@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.0.tgz#580fa8ab02cef22c24294d25e52d7ccd247a9a6a" - integrity sha512-/rHb32J2EJnEXeK4NpDgMaAVTFZS3o1ExmjKMtYVgIC4MQn0vkNSbYpdGRotkfGGRWiqk3Ri3FBkiZGbAfIfOQ== - -conventional-changelog-writer@^4.0.11: - version "4.0.11" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.11.tgz#9f56d2122d20c96eb48baae0bf1deffaed1edba4" - integrity sha512-g81GQOR392I+57Cw3IyP1f+f42ME6aEkbR+L7v1FBBWolB0xkjKTeCWVguzRrp6UiT1O6gBpJbEy2eq7AnV1rw== - dependencies: - compare-func "^1.3.1" - conventional-commits-filter "^2.0.2" - dateformat "^3.0.0" - handlebars "^4.4.0" - json-stringify-safe "^5.0.1" - lodash "^4.17.15" - meow "^5.0.0" - semver "^6.0.0" - split "^1.0.0" - through2 "^3.0.0" - -conventional-changelog@3.1.12: - version "3.1.12" - resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-3.1.12.tgz#ede5b6803cfa8af6c7ea97e54ce5519508903afb" - integrity sha512-zyGKwii8Z5zOq1nGFm5jn9Ou1jQ6UBoRT0+nqBIU8fEzh64+AcVxrY97tVuK77Ati0xwpBiFHpDXAW7pkq1jEw== - dependencies: - conventional-changelog-angular "^5.0.5" - conventional-changelog-atom "^2.0.3" - conventional-changelog-codemirror "^2.0.3" - conventional-changelog-conventionalcommits "^4.2.1" - conventional-changelog-core "^4.0.2" - conventional-changelog-ember "^2.0.4" - conventional-changelog-eslint "^3.0.4" - conventional-changelog-express "^2.0.1" - conventional-changelog-jquery "^3.0.6" - conventional-changelog-jshint "^2.0.3" - conventional-changelog-preset-loader "^2.2.0" - -conventional-commits-filter@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz#f122f89fbcd5bb81e2af2fcac0254d062d1039c1" - integrity sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ== - dependencies: - lodash.ismatch "^4.4.0" - modify-values "^1.0.0" +convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== -conventional-commits-parser@^3.0.5, conventional-commits-parser@^3.0.8: - version "3.0.8" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.8.tgz#23310a9bda6c93c874224375e72b09fb275fe710" - integrity sha512-YcBSGkZbYp7d+Cr3NWUeXbPDFUN6g3SaSIzOybi8bjHL5IJ5225OSCxJJ4LgziyEJ7AaJtE9L2/EU6H7Nt/DDQ== - dependencies: - JSONStream "^1.0.4" - is-text-path "^1.0.1" - lodash "^4.17.15" - meow "^5.0.0" - split2 "^2.0.0" - through2 "^3.0.0" - trim-off-newlines "^1.0.0" +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -conventional-recommended-bump@6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-6.0.2.tgz#086e3380e8d66ca2b962d84af863a28d532f355a" - integrity sha512-9qWhAweJbT6CAHcCprBYzUb3tySsaRrUx0ckpMprHbtWOBfl3gxakUCBNd/4T3m2Iv9Cb8Y4P2Px3cR5ysXPDw== - dependencies: - concat-stream "^2.0.0" - conventional-changelog-preset-loader "^2.2.0" - conventional-commits-filter "^2.0.2" - conventional-commits-parser "^3.0.5" - git-raw-commits "2.0.0" - git-semver-tags "^3.0.0" - meow "^4.0.0" - q "^1.5.1" - -convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== +cookie-parser@^1.4.6: + version "1.4.6" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.6.tgz#3ac3a7d35a7a03bbc7e365073a26074824214594" + integrity sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA== dependencies: - safe-buffer "~5.1.1" + cookie "0.4.1" + cookie-signature "1.0.6" cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== cookie@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-js-compat@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.2.tgz#314ca8b84d5e71c27c19f1ecda966501b1cf1f10" - integrity sha512-+G28dzfYGtAM+XGvB1C5AS1ZPKfQ47HLhcdeIQdZgQnJVdp7/D0m+W/TErwhgsX6CujRUk/LebB6dCrKrtJrvQ== - dependencies: - browserslist "^4.8.3" - semver "7.0.0" +cookie@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +cookie@0.4.2, cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cosmiconfig@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" + import-fresh "^3.2.1" parse-json "^5.0.0" path-type "^4.0.0" - yaml "^1.7.2" + yaml "^1.10.0" -create-ecdh@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" - integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== +crc@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6" + integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ== dependencies: - bn.js "^4.1.0" - elliptic "^6.0.0" + buffer "^5.1.0" -create-hash@^1.1.0, create-hash@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@6.0.5, cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -csp-header@^1.2.0: - version "1.3.3" - resolved "https://registry.yarnpkg.com/csp-header/-/csp-header-1.3.3.tgz#a1e2eb419caf0dfa60459ca58474789adfcb7a7d" - integrity sha512-0QR0rweH2GkpyYd6LzsUSokLGsQxF8sYfwD82HPuBc/a2h8cTVG/AyvR8DazmyVA8qlMiJDQ/LO7abXIPwcLtA== + cross-spawn "^7.0.1" -css-loader@^3.2.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.4.1.tgz#dfb7968aa9bffb26bd20375afdffe77d5a234b77" - integrity sha512-+ybmv7sVxxNEenQhkifQDvny/1iNQM7YooJbSfVUdQQvisyg1aKIqgGjCjoFSyVLJMp17z9rfZFQaR5HGHcMbw== +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: - camelcase "^5.3.1" - cssesc "^3.0.0" - icss-utils "^4.1.1" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.23" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.1.1" - postcss-modules-values "^3.0.0" - postcss-value-parser "^4.0.2" - schema-utils "^2.6.0" - -css-select@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +csrf@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/csrf/-/csrf-3.1.0.tgz#ec75e9656d004d674b8ef5ba47b41fbfd6cb9c30" + integrity sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w== + dependencies: + rndm "1.2.0" + tsscmp "1.0.6" + uid-safe "2.1.5" + +css-loader@^6.7.3: + version "6.7.3" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.3.tgz#1e8799f3ccc5874fdd55461af51137fcc5befbcd" + integrity sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.19" + 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-select@^4.1.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" - integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== - dependencies: - cssom "0.3.x" - -csstype@^2.2.0, csstype@^2.5.7: - version "2.6.8" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.8.tgz#0fb6fc2417ffd2816a418c9336da74d7f07db431" - integrity sha512-msVS9qTuMT5zwAGCVm4mxfrZ18BNc6Csd0oJAtiFMZ1FAx1CCvy2+5MDmYoix63LM/6NDbNtodCiGYGmFgO0dA== +csstype@^3.0.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= +csurf@^1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/csurf/-/csurf-1.11.0.tgz#ab0c3c6634634192bd3d6f4b861be20800eeb61a" + integrity sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ== dependencies: - array-find-index "^1.0.1" + cookie "0.4.0" + cookie-signature "1.0.6" + csrf "3.1.0" + http-errors "~1.7.3" cycle@1.0.x: version "1.0.3" resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" - integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI= - -cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= - -dargs@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" - integrity sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc= - dependencies: - number-is-nan "^1.0.0" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" + integrity sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA== -data-urls@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== +date-fns@^2.29.3: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" - -dateformat@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" - integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== - -dayjs@^1.8.18: - version "1.8.19" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.19.tgz#5117dc390d8f8e586d53891dbff3fa308f51abfe" - integrity sha512-7kqOoj3oQSmqbvtvGFLU5iYqies+SqUiEGNT0UtUPPxcPYgY1BrkXR0Cq2R9HYSimBXN+xHkEN4Hi399W+Ovlg== + "@babel/runtime" "^7.21.0" -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@4.1.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -debug@~3.1.0: +debug@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: ms "2.0.0" -debuglog@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= - -decamelize-keys@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" - integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= +debug@^3.1.0, debug@^3.2.5: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + ms "^2.1.1" -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== dependencies: mimic-response "^1.0.0" -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -define-properties@^1.1.2, define-properties@^1.1.3: +defer-to-connect@^1.0.1: version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== +define-properties@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" +denque@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +depd@2.0.0, depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -detect-file@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" - integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= +depd@~1.1.0, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -detect-indent@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" - integrity sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA== +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -detect-newline@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.0.0.tgz#8ae477c089e51872c264531cd6547719c0b86b2f" - integrity sha512-JAP22dVPAqvhdRFFxK1G5GViIokyUn0UWXRNW0ztK96fsqi9cuM8w8ESbSk+T2w5OVorcMcL6m7yUg1RrX+2CA== +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -detect-newline@^2.1.0: +detect-node@^2.0.4: version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== -dezalgo@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" - integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= +dezalgo@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" + integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== dependencies: asap "^2.0.0" wrappy "1" -diagnostics@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" - integrity sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ== - dependencies: - colorspace "1.1.x" - enabled "1.0.x" - kuler "1.0.x" +diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== -diff-sequences@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" - integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== - -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +dir-compare@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-2.4.0.tgz#785c41dc5f645b34343a4eafc50b79bac7f11631" + integrity sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA== + dependencies: + buffer-equal "1.0.0" + colors "1.0.3" + commander "2.9.0" + minimatch "3.0.4" -diff@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" - integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== +dmg-builder@22.14.5: + version "22.14.5" + resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.14.5.tgz#137c0b55e639badcc0b119eb060e6fa4ed61d948" + integrity sha512-1GvFGQE332bvPamcMwZDqWqfWfJTyyDLOsHMcGi0zs+Jh7JOn6/zuBkHJIWHdsj2QJbhzLVyd2/ZqttOKv7I8w== + dependencies: + app-builder-lib "22.14.5" + builder-util "22.14.5" + builder-util-runtime "8.9.1" + fs-extra "^10.0.0" + iconv-lite "^0.6.2" + js-yaml "^4.1.0" + optionalDependencies: + dmg-license "^1.0.9" -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" +dmg-license@^1.0.9: + version "1.0.11" + resolved "https://registry.yarnpkg.com/dmg-license/-/dmg-license-1.0.11.tgz#7b3bc3745d1b52be7506b4ee80cb61df6e4cd79a" + integrity sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q== + dependencies: + "@types/plist" "^3.0.1" + "@types/verror" "^1.10.3" + ajv "^6.10.0" + crc "^3.8.0" + iconv-corefoundation "^1.1.7" + plist "^3.0.4" + smart-buffer "^4.0.2" + verror "^1.10.0" + +doctypes@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" + integrity sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ== -dom-converter@^0.2: +dom-converter@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== dependencies: utila "~0.4" -dom-helpers@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" - integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== +dom-helpers@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" + integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== dependencies: - "@babel/runtime" "^7.1.2" + "@babel/runtime" "^7.8.7" + csstype "^3.0.2" -dom-serializer@0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== dependencies: domelementtype "^2.0.1" + domhandler "^4.2.0" entities "^2.0.0" -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - -domelementtype@1, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - -domelementtype@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" - integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== - -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== - dependencies: - webidl-conversions "^4.0.2" +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== dependencies: - domelementtype "1" + domelementtype "^2.2.0" -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== dependencies: - dom-serializer "0" - domelementtype "1" + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" -domutils@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== dependencies: - dom-serializer "0" - domelementtype "1" + no-case "^3.0.4" + tslib "^2.0.3" -dot-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" - integrity sha1-G3CK8JSknJoOfbyteQq6U52sEXc= +dot-prop@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== dependencies: - is-obj "^1.0.0" + is-obj "^2.0.0" -dotgitignore@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/dotgitignore/-/dotgitignore-2.1.0.tgz#a4b15a4e4ef3cf383598aaf1dfa4a04bcc089b7b" - integrity sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA== - dependencies: - find-up "^3.0.0" - minimatch "^3.0.4" +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +dotenv@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" + integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" +dotenv@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05" + integrity sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg== -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" +duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.3.322: - version "1.3.328" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.328.tgz#a619575c42f1d5b443103664f25ffa5a80190ee5" - integrity sha512-x4XefnFxDxFwaQ01d/pppJP9meWhOIJ/gtI6/4jqkpsadq79uL7NYSaX64naLmJqvzUBjSrO3IM2+1b/W9KdPg== - -elliptic@^6.0.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== - dependencies: - bn.js "^4.4.0" - brorand "^1.0.1" - hash.js "^1.0.0" - hmac-drbg "^1.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.0" - -"emberplus@https://github.com/nrkno/tv-automation-emberplus-connection.git": - version "1.7.8" - resolved "https://github.com/nrkno/tv-automation-emberplus-connection.git#5590e8ab8c9bbc3fb3d3f82d0fccc1861af11456" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +ejs@^3.1.6: + version "3.1.9" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + dependencies: + jake "^10.8.5" + +electron-builder@22.14.5: + version "22.14.5" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.14.5.tgz#3a25547bd4fe3728d4704da80956a794c5c31496" + integrity sha512-N73hSbXFz6Mz5Z6h6C5ly6CB+dUN6k1LuCDJjI8VF47bMXv/QE0HE+Kkb0GPKqTqM7Hsk/yIYX+kHCfSkR5FGg== + dependencies: + "@types/yargs" "^17.0.1" + app-builder-lib "22.14.5" + builder-util "22.14.5" + builder-util-runtime "8.9.1" + chalk "^4.1.1" + dmg-builder "22.14.5" + fs-extra "^10.0.0" + is-ci "^3.0.0" + lazy-val "^1.0.5" + read-config-file "6.2.0" + update-notifier "^5.1.0" + yargs "^17.0.1" + +electron-osx-sign@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.5.0.tgz#fc258c5e896859904bbe3d01da06902c04b51c3a" + integrity sha512-icoRLHzFz/qxzDh/N4Pi2z4yVHurlsCAYQvsCSG7fCedJ4UJXBS6PoQyGH71IfcqKupcKeK7HX/NkyfG+v6vlQ== + dependencies: + bluebird "^3.5.0" + compare-version "^0.1.2" + debug "^2.6.8" + isbinaryfile "^3.0.2" + minimist "^1.2.0" + plist "^3.0.1" + +electron-publish@22.14.5: + version "22.14.5" + resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.14.5.tgz#34bcdce671f0e651330db20040d6919c77c94bd6" + integrity sha512-h+NANRdaA0PqGF15GKvorseWPzh1PXa/zx4I37//PIokW8eKIov8ky23foUSb55ZFWUHGpxQJux7y2NCfBtQeg== + dependencies: + "@types/fs-extra" "^9.0.11" + builder-util "22.14.5" + builder-util-runtime "8.9.1" + chalk "^4.1.1" + fs-extra "^10.0.0" + lazy-val "^1.0.5" + mime "^2.5.2" + +electron-to-chromium@^1.4.284: + version "1.4.396" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.396.tgz#3d3664eb58d86376fbe2fece3705f68ca197205c" + integrity sha512-pqKTdqp/c5vsrc0xUPYXTDBo9ixZuGY8es4ZOjjd6HD6bFYbu5QA09VoW3fkY4LF1T0zYk86lN6bZnNlBuOpdQ== + +electron@16.2.6: + version "16.2.6" + resolved "https://registry.yarnpkg.com/electron/-/electron-16.2.6.tgz#2d22077edb5361ab52034bb3b19405380921931b" + integrity sha512-FJLnIu318WNh1WigMmWqSidOPwipwym2Qi3Hs/YY6znquztf6ZJuaq/TdJJyHIJHld+znG0hSmq3VbyW5KUr9A== + dependencies: + "@electron/get" "^1.13.0" + "@types/node" "^14.6.2" + extract-zip "^1.0.3" + +emberplus-connection@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/emberplus-connection/-/emberplus-connection-0.1.2.tgz#001bb1db4ac28d340af59e6fbe8b4d2574dc1373" + integrity sha512-oTxY2wyUbWTD2hSaQOvhrQnrgqpXrc39UPQUqPUwbdPpH3UX9mChLtHUrp1GU2zl+/UsCMaPcG+okf1Td268QQ== dependencies: asn1 evs-broadcast/node-asn1 + debug "^4.3.3" enum "^2.4.0" long "^3.2.0" smart-buffer "^3.0.3" - winston-color "^1.0.0" + tslib "^2.3.1" -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -enabled@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93" - integrity sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M= - dependencies: - env-variable "0.0.x" +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== -encodeurl@~1.0.2: +encodeurl@^1.0.2, encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -end-of-stream@^1.0.0, end-of-stream@^1.1.0: +end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -engine.io-client@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700" - integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA== - dependencies: - component-emitter "1.2.1" - component-inherit "0.0.3" - debug "~4.1.0" - engine.io-parser "~2.2.0" - has-cors "1.1.0" - indexof "0.0.1" - parseqs "0.0.5" - parseuri "0.0.5" - ws "~6.1.0" - xmlhttprequest-ssl "~1.5.4" - yeast "0.1.2" - -engine.io-parser@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" - integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== +endianness@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/endianness/-/endianness-8.0.2.tgz#e35d16bbe80b6ff94fbc199168dd234d9f78168e" + integrity sha512-IU+77+jJ7lpw2qZ3NUuqBZFy3GuioNgXUdsL1L9tooDNTaw0TgOnwNuc+8Ns+haDaTifK97QLzmOANJtI/rGvw== + +engine.io-client@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.4.0.tgz#88cd3082609ca86d7d3c12f0e746d12db4f47c91" + integrity sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g== dependencies: - after "0.8.2" - arraybuffer.slice "~0.0.7" - base64-arraybuffer "0.1.5" - blob "0.0.5" - has-binary2 "~1.0.2" + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.11.0" + xmlhttprequest-ssl "~2.0.0" -engine.io@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.4.0.tgz#3a962cc4535928c252759a00f98519cb46c53ff3" - integrity sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w== +engine.io-parser@~5.0.3: + version "5.0.6" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.6.tgz#7811244af173e157295dec9b2718dfe42a64ef45" + integrity sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw== + +engine.io@~6.4.1, engine.io@~6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.4.2.tgz#ffeaf68f69b1364b0286badddf15ff633476473f" + integrity sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg== dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" accepts "~1.3.4" base64id "2.0.0" - cookie "0.3.1" - debug "~4.1.0" - engine.io-parser "~2.2.0" - ws "^7.1.2" - -enhanced-resolve@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - tapable "^1.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.11.0" -enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" - integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== +enhanced-resolve@^5.0.0, enhanced-resolve@^5.14.0: + version "5.14.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.14.0.tgz#0b6c676c8a3266c99fa281e4433a706f5c0c61c4" + integrity sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw== dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" - -entities@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + graceful-fs "^4.2.4" + tapable "^2.2.0" entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" - integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== enum@^2.4.0: version "2.5.0" resolved "https://registry.yarnpkg.com/enum/-/enum-2.5.0.tgz#f205b8c65a335a8ace8081105df971b18568b984" - integrity sha1-8gW4xlozWorOgIEQXflxsYVouYQ= + integrity sha512-IN9mE0yf+9DoUvGpNQfvJNJ9HyS9VGeo7llLkPdRBtMU2LHLXiQ/JcOI03u8lig0lefGCewv9x82vK8LI8rNPg== dependencies: is-buffer "^1.1.0" -env-variable@0.0.x: - version "0.0.5" - resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88" - integrity sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA== +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== -errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== - dependencies: - prr "~1.0.1" +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0-next.1: - version "1.17.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" - integrity sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" - -es-to-primitive@^1.2.1: +es-module-lexer@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.2.1.tgz#ba303831f63e6a394983fde2f97ad77b22324527" + integrity sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg== + +es6-error@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -escodegen@^1.9.1: - version "1.12.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.1.tgz#08770602a74ac34c7a90ca9229e7d51e379abc76" - integrity sha512-Q8t2YZ+0e0pc7NRVj3B4tSQ9rim1oi4Fh46k2xhJ2qOiEwhQfdjyEQddWdj7ZFaKmU+5104vn1qrcjEPWq+bgQ== - dependencies: - esprima "^3.1.3" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: - esrecurse "^4.1.0" + esrecurse "^4.3.0" estraverse "^4.1.1" -esprima@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= - esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -esutils@^2.0.0, esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -events@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" +eventemitter3@^4.0.4, eventemitter3@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" + 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" + +execa@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" + integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + +exit-hook@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-2.2.1.tgz#007b2d92c6428eda2b76e7016a34351586934593" + integrity sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw== exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -expand-tilde@^2.0.0, expand-tilde@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= - dependencies: - homedir-polyfill "^1.0.1" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expect@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" - integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== +expect@^29.0.0, expect@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" + integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== dependencies: - "@jest/types" "^24.9.0" - ansi-styles "^3.2.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.9.0" + "@jest/expect-utils" "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" -express-csp-header@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/express-csp-header/-/express-csp-header-2.3.2.tgz#a833a7f96795a889fb569c7d17f6fbbede60d58f" - integrity sha512-E2oZ3CAudvSM78S0uNw1x1XOXwBDSUaFEpBBY2U7nb1VBHfegTezY4n2MKjCaaGo0xPceKCJESACc5gkF7jY7A== +express-session@^1.17.3: + version "1.17.3" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.3.tgz#14b997a15ed43e5949cb1d073725675dd2777f36" + integrity sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw== dependencies: - csp-header "^1.2.0" - parse-domain "2.1.8" + cookie "0.4.2" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~2.0.0" + on-headers "~1.0.2" + parseurl "~1.3.3" + safe-buffer "5.2.1" + uid-safe "~2.1.5" -express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== +express@^4.18.1, express@^4.18.2: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== dependencies: - accepts "~1.3.7" + accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" + body-parser "1.20.1" + content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.4.0" + cookie "0.5.0" cookie-signature "1.0.6" debug "2.6.9" - depd "~1.1.2" + depd "2.0.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "~1.1.2" + 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.3.0" + on-finished "2.4.1" parseurl "~1.3.3" path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" + proxy-addr "~2.0.7" + qs "6.11.0" range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" + 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" -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.2: +extend@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= +extract-zip@^1.0.3: + version "1.7.0" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" + integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA== + dependencies: + concat-stream "^1.6.2" + debug "^2.6.9" + mkdirp "^0.5.4" + yauzl "^2.10.0" extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== eyes@0.1.x: version "0.1.8" resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" - integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A= + integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fast-safe-stringify@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" - integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== - -fastestsmallesttextencoderdecoder@^1.0.7: - version "1.0.14" - resolved "https://registry.yarnpkg.com/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.14.tgz#ef5d331ab5aeee83f837187f1571d30f5c365e79" - integrity sha512-ov+uDh4DMZHpZvcGwlCb9tfntaHwRI7SK+/6XkdXhksZLJcMoTJ20FZx3GvujnsGjMvJVQ71LkduEUEPwX1BvQ== +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" -fecha@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" - integrity sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg== - -figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== - -figures@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.0.0.tgz#756275c964646163cc6f9197c7a0295dbfd04de9" - integrity sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g== - dependencies: - escape-string-regexp "^1.0.5" - -file-loader@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" - integrity sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA== +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== dependencies: - loader-utils "^1.2.3" - schema-utils "^2.5.0" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + pend "~1.2.0" -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" + minimatch "^5.0.1" fill-range@^7.0.1: version "7.0.1" @@ -3579,41 +3237,25 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== dependencies: debug "2.6.9" encodeurl "~1.0.2" escape-html "~1.0.3" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" - statuses "~1.5.0" + statuses "2.0.1" unpipe "~1.0.0" -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - find-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== -find-up@3.0.0, find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@4.1.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -3621,429 +3263,321 @@ find-up@4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" +follow-redirects@^1.14.9: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== -findup-sync@3.0.0: +foreachasync@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" - integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - -flat@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" - integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== - dependencies: - is-buffer "~2.0.3" + resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6" + integrity sha512-J+ler7Ta54FwwNcx6wQRDhTIbNeyDcARMkOcguEqnEdtm0jKvN3Li3PDAb2Du3ubJYEWfYL83XMROXdsXAXycw== -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + cross-spawn "^7.0.0" + signal-exit "^4.0.1" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= +formidable@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-2.1.1.tgz#81269cbea1a613240049f5f61a9d97731517414f" + integrity sha512-0EcS9wCFEzLvfiks7omJ+SiYJAiD+TzK4Pcw1UlUoGnhUxDcMKjt0P7x8wEb0u6OHu8Nb98WG3nxtlF5C7bvUQ== dependencies: - map-cache "^0.2.2" + dezalgo "^1.0.4" + hexoid "^1.0.0" + once "^1.4.0" + qs "^6.11.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -from2@^2.1.0, from2@^2.1.1, from2@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" -fs-access@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a" - integrity sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o= +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: - null-check "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= +fs-extra@^9.0.0, fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^1.2.7: - version "1.2.11" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" - integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" +fsevents@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -get-caller-file@^2.0.1: +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + +gdnet-asn1@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gdnet-asn1/-/gdnet-asn1-1.0.0.tgz#4f2bb0444a8ddc1fad7fc2850c23889ac17dff15" + integrity sha512-oIFd2YLpXwlBQCl7ZOAtl1ZkZVjnoKhsLJrOPeeBkPUxlUQ2pUmQiGKCLMMNjFYRK+fvERl6O4MZnghVBYRXBg== + dependencies: + "@types/safer-buffer" "^2.1.0" + safer-buffer "~2.1.0" + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -get-pkg-repo@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" - integrity sha1-xztInAbYDMVTbCyFP54FIyBWly0= +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== dependencies: - hosted-git-info "^2.1.4" - meow "^3.3.0" - normalize-package-data "^2.3.0" - parse-github-repo-url "^1.3.0" - through2 "^2.0.0" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" -get-stream@3.0.0, get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-stream@^4.0.0: +get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== dependencies: pump "^3.0.0" -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -git-raw-commits@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.0.tgz#d92addf74440c14bcc5c83ecce3fb7f8a79118b5" - integrity sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg== - dependencies: - dargs "^4.0.1" - lodash.template "^4.0.2" - meow "^4.0.0" - split2 "^2.0.0" - through2 "^2.0.0" - -git-remote-origin-url@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" - integrity sha1-UoJlna4hBxRaERJhEq0yFuxfpl8= - dependencies: - gitconfiglocal "^1.0.0" - pify "^2.3.0" - -git-semver-tags@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-3.0.0.tgz#fe10147824657662c82efd9341f0fa59f74ddcba" - integrity sha512-T4C/gJ9k2Bnxz+PubtcyiMtUUKrC+Nh9Q4zaECcnmVMwJgPhrNyP/Rf+YpdRqsJbCV/+kYrCH24Xg+IeAmbOPg== - dependencies: - meow "^4.0.0" - semver "^6.0.0" - -git-semver-tags@^3.0.0, git-semver-tags@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-3.0.1.tgz#9cb9e4974437de1f71f32da3bfe74f4d35afb1b9" - integrity sha512-Hzd1MOHXouITfCasrpVJbRDg9uvW7LfABk3GQmXYZByerBDrfrEMP9HXpNT7RxAbieiocP6u+xq20DkvjwxnCA== +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: - meow "^5.0.0" - semver "^6.0.0" + pump "^3.0.0" -gitconfiglocal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" - integrity sha1-QdBF84UaXqiPA/JMocYXgRRGS5s= - dependencies: - ini "^1.3.2" +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -"glob-all@3.1.0 ": +glob-all@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab" - integrity sha1-iRPd+17hrHgSZWJBsD1SF8ZLAqs= + integrity sha512-B61R+opn9HMe8dD170uIn9SP5gGMP+kUmvQXbCZun7h4MB6JKbPAITaR8WU3N2Ry10r/keBCTsz0DE34L+biWg== dependencies: glob "^7.0.5" yargs "~1.2.6" -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== +glob@^10.0.0: + version "10.2.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.4.tgz#f5bf7ddb080e3e9039b148a9e2aef3d5ebfc0a25" + integrity sha512-fDboBse/sl1oXSLhIp0FcCJgzW9KmhC/q8ULTKC82zc+DL3TL7FNb8qlt5qqXN53MsKEUSIcb+7DLmEygOE5Yw== dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.0" + minipass "^5.0.0 || ^6.0.0" + path-scurry "^1.7.0" -glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== +glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^3.1.1" once "^1.3.0" path-is-absolute "^1.0.0" -global-modules@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-modules@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" - integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== +global-agent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6" + integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q== dependencies: - global-prefix "^1.0.1" - is-windows "^1.0.1" - resolve-dir "^1.0.0" + boolean "^3.0.1" + es6-error "^4.1.1" + matcher "^3.0.0" + roarr "^2.15.3" + semver "^7.3.2" + serialize-error "^7.0.1" -global-prefix@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= +global-dirs@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" + integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== dependencies: - expand-tilde "^2.0.2" - homedir-polyfill "^1.0.1" - ini "^1.3.4" - is-windows "^1.0.1" - which "^1.2.14" + ini "2.0.0" -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== +global-tunnel-ng@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f" + integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg== dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" + encodeurl "^1.0.2" + lodash "^4.17.10" + npm-conf "^1.1.3" + tunnel "^0.0.6" globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -got@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" - integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== +globalthis@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== dependencies: - "@sindresorhus/is" "^0.7.0" - cacheable-request "^2.1.1" + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" decompress-response "^3.3.0" duplexer3 "^0.1.4" - get-stream "^3.0.0" - into-stream "^3.1.0" - is-retry-allowed "^1.1.0" - isurl "^1.0.0-alpha5" - lowercase-keys "^1.0.0" - mimic-response "^1.0.0" - p-cancelable "^0.4.0" - p-timeout "^2.0.1" - pify "^3.0.0" - safe-buffer "^5.1.1" - timed-out "^4.0.1" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" - url-to-options "^1.0.1" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== "graceful-readlink@>= 1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + integrity sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w== -handlebars@^4.1.2, handlebars@^4.4.0: - version "4.5.3" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482" - integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA== +handlebars@4.7.7: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== dependencies: + minimist "^1.2.5" neo-async "^2.6.0" - optimist "^0.6.1" source-map "^0.6.1" + wordwrap "^1.0.0" optionalDependencies: uglify-js "^3.1.4" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-binary2@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" - integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== - dependencies: - isarray "2.0.1" - -has-cors@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" - integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== -has-symbol-support-x@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" - integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-to-string-tag-x@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" - integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== dependencies: - has-symbol-support-x "^1.4.1" + get-intrinsic "^1.1.1" -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-value@^1.0.0: +has-tostringtag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" + has-symbols "^1.0.2" -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" +has-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== has@^1.0.3: version "1.0.3" @@ -4052,122 +3586,126 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== +hbs@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hbs/-/hbs-4.2.0.tgz#10e40dcc24d5be7342df9636316896617542a32b" + integrity sha512-dQwHnrfWlTk5PvG9+a45GYpg0VpX47ryKF8dULVd6DtwOE6TEcYQXQ5QM6nyOx/h7v3bvEQbdn19EDAcfUAgZg== dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" + handlebars "4.7.7" + walk "2.3.15" -he@1.2.0, he@1.2.x: +he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +helmet@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-6.2.0.tgz#c29d62014be4c70b8ef092c9c5e54c8c26b8e16e" + integrity sha512-DWlwuXLLqbrIOltR6tFQXShj/+7Cyp0gLi6uAb8qMdFh/YBBFbKSgQ6nbXmScYd8emMctuthmgIa7tUfo9Rtyg== + +hexoid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18" + integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g== + highland@^3.0.0-beta.6: version "3.0.0-beta.10" resolved "https://registry.yarnpkg.com/highland/-/highland-3.0.0-beta.10.tgz#e07869611de2109134c523e2479ef5af5334c112" integrity sha512-fBxAarP4g0AFWRKd+SJBWsKmkyw1WZdQZ1jjFSAVrxLXIhEo5NnEBy+rDEM695Z/i4/tP2lMYW6iuotStDFHYw== -hmac-drbg@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" + react-is "^16.7.0" -hoist-non-react-statics@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#101685d3aff3b23ea213163f6e8e12f4f111e19f" - integrity sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw== +hosted-git-info@^2.7.1: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hosted-git-info@^4.0.1, hosted-git-info@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== dependencies: - react-is "^16.7.0" + lru-cache "^6.0.0" -homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== + dependencies: + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" + he "^1.2.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.10.0" + +html-parse-stringify@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" + integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== dependencies: - parse-passwd "^1.0.0" + void-elements "3.1.0" -hosted-git-info@^2.1.4, hosted-git-info@^2.1.5: - version "2.8.5" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" - integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== +html-webpack-plugin@^5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz#826838e31b427f5f7f30971f8d8fa2422dfa6763" + integrity sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== dependencies: - whatwg-encoding "^1.0.1" + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" -html-minifier@^3.2.3: - version "3.5.21" - resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" - integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== dependencies: - camel-case "3.0.x" - clean-css "4.2.x" - commander "2.17.x" - he "1.2.x" - param-case "2.1.x" - relateurl "0.2.x" - uglify-js "3.4.x" + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" -html-webpack-plugin@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" - integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= - dependencies: - html-minifier "^3.2.3" - loader-utils "^0.2.16" - lodash "^4.17.3" - pretty-error "^2.0.2" - tapable "^1.0.0" - toposort "^1.0.0" - util.promisify "1.0.0" - -htmlparser2@^3.3.0: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - -http-cache-semantics@3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" - integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== - -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== dependencies: depd "~1.1.2" inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" -http-errors@~1.7.2: +http-errors@~1.7.3: version "1.7.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== @@ -4178,24 +3716,37 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +i18next-browser-languagedetector@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.0.1.tgz#ead34592edc96c6c3a618a51cb57ad027c5b5d87" + integrity sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g== dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + "@babel/runtime" "^7.19.4" -http@^0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/http/-/http-0.0.0.tgz#86e6326d29c5d039de9fac584a45689f929f4f72" - integrity sha1-huYybSnF0Dnen6xYSkVon5KfT3I= +i18next@^20.6.1: + version "20.6.1" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-20.6.1.tgz#535e5f6e5baeb685c7d25df70db63bf3cc0aa345" + integrity sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A== + dependencies: + "@babel/runtime" "^7.12.0" -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +iconv-corefoundation@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz#31065e6ab2c9272154c8b0821151e2c88f1b002a" + integrity sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ== + dependencies: + cli-truncate "^2.1.0" + node-addon-api "^1.6.3" iconv-lite@0.4.24: version "0.4.24" @@ -4204,188 +3755,127 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -icss-utils@^4.0.0, icss-utils@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: - postcss "^7.0.14" + safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= +ieee754-buffer@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ieee754-buffer/-/ieee754-buffer-0.2.1.tgz#7e0d7d381d228de949f06b71f1cfd971691271f6" + integrity sha512-dDlJhYk8BAmH1HDncTjCt6xOm2+kT+MxGhRKB+mUoF8nocDzPAgZPEWTRI9QgkGvbDkbJgCqyxweGlIV0yhbUQ== -import-fresh@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +imaadpcm@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/imaadpcm/-/imaadpcm-4.1.2.tgz#8757742610004bc2aba1181919f899abd6a9b413" + integrity sha512-7gwxe6lKCGitmkMtGbm1ecnt0Q59KcWwo7AVi2RAd3lQ9VghVN5zX5x3oK6xNhfD9KUMbaYzku43UBn3Ix3RIA== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" -import-local@2.0.0, import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= - dependencies: - repeating "^2.0.0" - -indent-string@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" - integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= - -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== -infer-owner@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= - inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@^1.3.2, ini@^1.3.4, ini@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -interpret@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== - -into-stream@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" - integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= - dependencies: - from2 "^2.1.1" - p-is-promise "^1.1.0" - -into-stream@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-5.1.1.tgz#f9a20a348a11f3c13face22763f2d02e127f4db8" - integrity sha512-krrAJ7McQxGGmvaYbB7Q1mcA+cRwg9Ij2RfWIeVesNBgVDZmzY/Fa4IpZUT3bmdRzMzdf/mzltCG2Dq99IZGBA== - dependencies: - from2 "^2.3.0" - p-is-promise "^3.0.0" - -invariant@^2.2.2, invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -invert-kv@^2.0.0: +ini@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ipaddr.js@1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" - integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA== +ini@^1.3.4, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" +interpret@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" + integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== + +ioredis@^5.2.3: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7" + integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== + dependencies: + "@ioredis/commands" "^1.1.1" + cluster-key-slot "^1.1.0" + debug "^4.3.4" + denque "^2.1.0" + lodash.defaults "^4.2.0" + lodash.isarguments "^3.1.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + standard-as-callback "^2.1.0" -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== -is-buffer@^1.1.0, is-buffer@^1.1.5: +is-buffer@^1.1.0: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== - -is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -4393,898 +3883,759 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== +is-ci@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + ci-info "^3.2.0" -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== +is-core-module@^2.11.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" + integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + has "^1.0.3" -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= +is-expression@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" + integrity sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A== dependencies: - number-is-nan "^1.0.0" + acorn "^7.1.1" + object-assign "^4.1.1" -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== is-generator-fn@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== dependencies: - is-extglob "^2.1.1" + global-dirs "^3.0.0" + is-path-inside "^3.0.2" -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" +is-npm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" + integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -is-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" - integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-object@^2.0.3, is-plain-object@^2.0.4: +is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" -is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== - dependencies: - has "^1.0.3" +is-promise@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-retry-allowed@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== +is-regex@^1.0.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-running@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-running/-/is-running-2.1.0.tgz#30a73ff5cc3854e4fc25490809e9f5abf8de09e0" + integrity sha512-mjJd3PujZMl7j+D395WTIO5tU5RIDBfVSRtRR4VOJou3H66E38UjbjvDGh3slJzPuolsb+yQFqwHNNdyp5jg3w== -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-text-path@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" - integrity sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= - dependencies: - text-extensions "^1.0.0" +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== -is-typedarray@~1.0.0: +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-windows@^1.0.1, is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: +isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== -isarray@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" - integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= +isbinaryfile@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" + integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== + dependencies: + buffer-alloc "^1.2.0" + +isbinaryfile@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isobject@^3.0.0, isobject@^3.0.1: +isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isstream@0.1.x, isstream@~0.1.2: +isstream@0.1.x: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" - integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== -istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" - integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== - dependencies: - "@babel/generator" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - istanbul-lib-coverage "^2.0.5" - semver "^6.0.0" +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" -istanbul-lib-report@^2.0.4: - version "2.0.8" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" - integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== dependencies: - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - supports-color "^6.1.0" + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" -istanbul-lib-source-maps@^3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" - integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - rimraf "^2.6.3" + istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.6.tgz#7b4f2660d82b29303a8fe6091f8ca4bf058da1af" - integrity sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA== +istanbul-reports@^3.1.3: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== dependencies: - handlebars "^4.1.2" + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" -isurl@^1.0.0-alpha5: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" - integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== - dependencies: - has-to-string-tag-x "^1.2.0" - is-object "^1.0.1" - -jazz-midi@^1.7.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/jazz-midi/-/jazz-midi-1.7.1.tgz#ded957468a23e07bf73111c76f74a794ad609515" - integrity sha512-yHA9uy+OYbEXKwiAq6dPjgJ+2mB+xH9f1WWegWdqKy0rENiLJ8QHrEkkposltjnEza8pBm1IOfxzcEOIF+YTgQ== - -jest-changed-files@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" - integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== - dependencies: - "@jest/types" "^24.9.0" - execa "^1.0.0" - throat "^4.0.0" - -jest-cli@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" - integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== - dependencies: - "@jest/core" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - exit "^0.1.2" - import-local "^2.0.0" - is-ci "^2.0.0" - jest-config "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - prompts "^2.0.1" - realpath-native "^1.1.0" - yargs "^13.3.0" - -jest-config@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" - integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== - dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.9.0" - "@jest/types" "^24.9.0" - babel-jest "^24.9.0" - chalk "^2.0.1" - glob "^7.1.1" - jest-environment-jsdom "^24.9.0" - jest-environment-node "^24.9.0" - jest-get-type "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - micromatch "^3.1.10" - pretty-format "^24.9.0" - realpath-native "^1.1.0" - -jest-diff@^24.3.0, jest-diff@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" - integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-docblock@^24.3.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" - integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== - dependencies: - detect-newline "^2.1.0" - -jest-each@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" - integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== - dependencies: - "@jest/types" "^24.9.0" - chalk "^2.0.1" - jest-get-type "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - -jest-environment-jsdom@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" - integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - jsdom "^11.5.1" - -jest-environment-node@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" - integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - -jest-get-type@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" - integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== - -jest-haste-map@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" - integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== - dependencies: - "@jest/types" "^24.9.0" - anymatch "^2.0.0" - fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.9.0" - micromatch "^3.1.10" - sane "^4.0.3" - walker "^1.0.7" +jackspeak@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.0.tgz#497cbaedc902ec3f31d5d61be804d2364ff9ddad" + integrity sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ== + dependencies: + "@isaacs/cliui" "^8.0.2" optionalDependencies: - fsevents "^1.2.7" - -jest-jasmine2@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" - integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== - dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" + "@pkgjs/parseargs" "^0.11.0" + +jake@^10.8.5: + version "10.8.6" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.6.tgz#227a96786a1e035214e0ba84b482d6223d41ef04" + integrity sha512-G43Ub9IYEFfu72sua6rzooi8V8Gz2lkfk48rW20vEWCGizeaEPlKB1Kh8JIA84yQbiAEfqlPmSpGgCKKxH3rDA== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + +jazz-midi@^1.7.9: + version "1.7.9" + resolved "https://registry.yarnpkg.com/jazz-midi/-/jazz-midi-1.7.9.tgz#ad564e85acf12414aec7ef7d879ad61a5d7f6896" + integrity sha512-c8c4BBgwxdsIr1iVm53nadCrtH7BUlnX3V95ciK/gbvXN/ndE5+POskBalXgqlc/r9p2XUbdLTrgrC6fou5p9w== + +jest-changed-files@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" + integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + +jest-circus@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.5.0.tgz#b5926989449e75bff0d59944bae083c9d7fb7317" + integrity sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA== + dependencies: + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" co "^4.6.0" - expect "^24.9.0" + dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - throat "^4.0.0" - -jest-leak-detector@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" - integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== - dependencies: - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-matcher-utils@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" - integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== - dependencies: - chalk "^2.0.1" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-message-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" - integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/stack-utils" "^1.0.1" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" - -jest-mock@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" - integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== - dependencies: - "@jest/types" "^24.9.0" - -jest-pnp-resolver@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" - integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== - -jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" - integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== - -jest-resolve-dependencies@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" - integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== - dependencies: - "@jest/types" "^24.9.0" - jest-regex-util "^24.3.0" - jest-snapshot "^24.9.0" - -jest-resolve@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" - integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== - dependencies: - "@jest/types" "^24.9.0" - browser-resolve "^1.11.3" - chalk "^2.0.1" - jest-pnp-resolver "^1.2.1" - realpath-native "^1.1.0" - -jest-runner@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" - integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.4.2" - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-docblock "^24.3.0" - jest-haste-map "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-leak-detector "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" - source-map-support "^0.5.6" - throat "^4.0.0" - -jest-runtime@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" - integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - chalk "^2.0.1" + jest-each "^29.5.0" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" + p-limit "^3.1.0" + pretty-format "^29.5.0" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.5.0.tgz#b34c20a6d35968f3ee47a7437ff8e53e086b4a67" + integrity sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw== + dependencies: + "@jest/core" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" + chalk "^4.0.0" exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" + prompts "^2.0.1" + yargs "^17.3.1" + +jest-config@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.5.0.tgz#3cc972faec8c8aaea9ae158c694541b79f3748da" + integrity sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.5.0" + "@jest/types" "^29.5.0" + babel-jest "^29.5.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" glob "^7.1.3" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - realpath-native "^1.1.0" - slash "^2.0.0" - strip-bom "^3.0.0" - yargs "^13.3.0" - -jest-serializer@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" - integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== - -jest-snapshot@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" - integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== - dependencies: - "@babel/types" "^7.0.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - expect "^24.9.0" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - mkdirp "^0.5.1" + graceful-fs "^4.2.9" + jest-circus "^29.5.0" + jest-environment-node "^29.5.0" + jest-get-type "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-runner "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.5.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" + integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + +jest-docblock@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.5.0.tgz#fc6e7014f83eac68e22b7195598de8554c2e5c06" + integrity sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA== + dependencies: + "@jest/types" "^29.5.0" + chalk "^4.0.0" + jest-get-type "^29.4.3" + jest-util "^29.5.0" + pretty-format "^29.5.0" + +jest-environment-node@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.5.0.tgz#f17219d0f0cc0e68e0727c58b792c040e332c967" + integrity sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw== + dependencies: + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + jest-mock "^29.5.0" + jest-util "^29.5.0" + +jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== + +jest-haste-map@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.5.0.tgz#69bd67dc9012d6e2723f20a945099e972b2e94de" + integrity sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA== + dependencies: + "@jest/types" "^29.5.0" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" + jest-worker "^29.5.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz#cf4bdea9615c72bac4a3a7ba7e7930f9c0610c8c" + integrity sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow== + dependencies: + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + +jest-matcher-utils@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" + integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== + dependencies: + chalk "^4.0.0" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" + +jest-message-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" + integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.5.0" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.5.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.5.0.tgz#26e2172bcc71d8b0195081ff1f146ac7e1518aed" + integrity sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw== + dependencies: + "@jest/types" "^29.5.0" + "@types/node" "*" + jest-util "^29.5.0" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== + +jest-resolve-dependencies@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz#f0ea29955996f49788bf70996052aa98e7befee4" + integrity sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg== + dependencies: + jest-regex-util "^29.4.3" + jest-snapshot "^29.5.0" + +jest-resolve@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.5.0.tgz#b053cc95ad1d5f6327f0ac8aae9f98795475ecdc" + integrity sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.5.0" + jest-pnp-resolver "^1.2.2" + jest-util "^29.5.0" + jest-validate "^29.5.0" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-runner@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.5.0.tgz#6a57c282eb0ef749778d444c1d758c6a7693b6f8" + integrity sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ== + dependencies: + "@jest/console" "^29.5.0" + "@jest/environment" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.4.3" + jest-environment-node "^29.5.0" + jest-haste-map "^29.5.0" + jest-leak-detector "^29.5.0" + jest-message-util "^29.5.0" + jest-resolve "^29.5.0" + jest-runtime "^29.5.0" + jest-util "^29.5.0" + jest-watcher "^29.5.0" + jest-worker "^29.5.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.5.0.tgz#c83f943ee0c1da7eb91fa181b0811ebd59b03420" + integrity sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw== + dependencies: + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/globals" "^29.5.0" + "@jest/source-map" "^29.4.3" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.5.0.tgz#c9c1ce0331e5b63cd444e2f95a55a73b84b1e8ce" + integrity sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.5.0" + graceful-fs "^4.2.9" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" natural-compare "^1.4.0" - pretty-format "^24.9.0" - semver "^6.2.0" - -jest-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" - integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== - dependencies: - "@jest/console" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/source-map" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" - is-ci "^2.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" - -jest-validate@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" - integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== - dependencies: - "@jest/types" "^24.9.0" - camelcase "^5.3.1" - chalk "^2.0.1" - jest-get-type "^24.9.0" + pretty-format "^29.5.0" + semver "^7.3.5" + +jest-util@^29.0.0, jest-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" + integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== + dependencies: + "@jest/types" "^29.5.0" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.5.0.tgz#8e5a8f36178d40e47138dc00866a5f3bd9916ffc" + integrity sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ== + dependencies: + "@jest/types" "^29.5.0" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.4.3" leven "^3.1.0" - pretty-format "^24.9.0" - -jest-watcher@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" - integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== - dependencies: - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - jest-util "^24.9.0" - string-length "^2.0.0" - -jest-worker@^24.6.0, jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== + pretty-format "^29.5.0" + +jest-watcher@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.5.0.tgz#cf7f0f949828ba65ddbbb45c743a382a4d911363" + integrity sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA== + dependencies: + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.5.0" + string-length "^4.0.1" + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest-worker@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.5.0.tgz#bdaefb06811bd3384d93f009755014d8acb4615d" + integrity sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA== dependencies: + "@types/node" "*" + jest-util "^29.5.0" merge-stream "^2.0.0" - supports-color "^6.1.0" + supports-color "^8.0.0" -jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" - integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== +jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.5.0.tgz#f75157622f5ce7ad53028f2f8888ab53e1f1f24e" + integrity sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ== dependencies: - import-local "^2.0.0" - jest-cli "^24.9.0" + "@jest/core" "^29.5.0" + "@jest/types" "^29.5.0" + import-local "^3.0.2" + jest-cli "^29.5.0" -js-levenshtein@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" - integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== +js-stringify@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" + integrity sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsdom@^11.5.1: - version "11.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" - integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== - dependencies: - abab "^2.0.0" - acorn "^5.5.3" - acorn-globals "^4.1.0" - array-equal "^1.0.0" - cssom ">= 0.3.2 < 0.4.0" - cssstyle "^1.0.0" - data-urls "^1.0.0" - domexception "^1.0.1" - escodegen "^1.9.1" - html-encoding-sniffer "^1.0.2" - left-pad "^1.3.0" - nwsapi "^2.0.7" - parse5 "4.0.0" - pn "^1.1.0" - request "^2.87.0" - request-promise-native "^1.0.5" - sax "^1.2.4" - symbol-tree "^3.2.2" - tough-cookie "^2.3.4" - w3c-hr-time "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.3" - whatwg-mimetype "^2.1.0" - whatwg-url "^6.4.1" - ws "^5.2.0" - xml-name-validator "^3.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== -json5@2.x, json5@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" - integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== - dependencies: - minimist "^1.2.0" +json5@^2.2.0, json5@^2.2.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -json5@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== dependencies: - minimist "^1.2.0" - -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= +jstransformer@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" + integrity sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A== dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" + is-promise "^2.0.0" + promise "^7.0.1" -jzz@^0.8.7: - version "0.8.9" - resolved "https://registry.yarnpkg.com/jzz/-/jzz-0.8.9.tgz#99efc6cb49644c542c659cfc927c8fd79283a0f4" - integrity sha512-R18OGWHL9NDsNFWTMtE+4Mky/FJwA67YNIJ+bbdoFY3xz/DIQtghSSkGV2W/iCqYoV17FV5mzRocDxgJ7/QTfw== +jzz@^1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/jzz/-/jzz-1.6.3.tgz#8f6e835c35aa2456a681678969a6915b62998845" + integrity sha512-o4JRIYzmkYj4+2cnuyskBfU11M9VjD/gPuAb4iRaRJN+Ti8lmDC7uw5c5tIUMyUlPxikimyZgOckUnhw7SelVg== dependencies: - jazz-midi "^1.7.0" + "@types/webmidi" "^2.0.7" + jazz-midi "^1.7.9" -keyv@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" - integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== dependencies: json-buffer "3.0.0" -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -kuler@1.0.x: - version "1.0.1" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6" - integrity sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ== - dependencies: - colornames "^1.1.1" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== +latest-version@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== dependencies: - invert-kv "^2.0.0" + package-json "^6.3.0" -left-pad@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" - integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== +lazy-val@^1.0.4, lazy-val@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.5.tgz#6cf3b9f5bc31cee7ee3e369c0832b7583dcd923d" + integrity sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q== leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" +lilconfig@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== - -loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== - dependencies: - big.js "^5.2.2" - emojis-list "^2.0.0" - json5 "^1.0.1" - -loader-utils@^0.2.16: - version "0.2.17" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" - integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - object-assign "^4.0.1" + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +lint-staged@^13.2.2: + version "13.2.2" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.2.2.tgz#5e711d3139c234f73402177be2f8dd312e6508ca" + integrity sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA== + dependencies: + chalk "5.2.0" + cli-truncate "^3.1.0" + commander "^10.0.0" + debug "^4.3.4" + execa "^7.0.0" + lilconfig "2.1.0" + listr2 "^5.0.7" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-inspect "^1.12.3" + pidtree "^0.6.0" + string-argv "^0.3.1" + yaml "^2.2.2" + +listr2@^5.0.7: + version "5.0.8" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.8.tgz#a9379ffeb4bd83a68931a65fb223a11510d6ba23" + integrity sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.19" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.8.0" + through "^2.3.8" + wrap-ansi "^7.0.0" + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -locate-path@^2.0.0: +loadware@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + resolved "https://registry.yarnpkg.com/loadware/-/loadware-2.0.0.tgz#57a72b6f18ee2baff8d1ad1fa05a5d16e5afd42c" + integrity sha512-PD5Yn9VFr7RTJLvIx/CBRALvE+PATUDoEedCcik49Te30LK4qU39DZPV3oxhhF9ql9NKg3kwL+kyf0NqnX9e/g== dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" + app-module-path "^2.1.0" locate-path@^5.0.0: version "5.0.0" @@ -5293,75 +4644,72 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw== + +lodash.assignin@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + integrity sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg== + +lodash.clone@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + integrity sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg== + +lodash.clonedeep@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== -lodash.ismatch@^4.4.0: +lodash.flatten@^4.4.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" - integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g== + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== + +lodash.isarguments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - -lodash.omit@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" - integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA= - -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - -lodash.template@^4.0.2: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== - dependencies: - lodash._reinterpolate "^3.0.0" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== -lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lodash.set@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" + integrity sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg== -log-symbols@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== - dependencies: - chalk "^2.0.1" +lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -logform@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.1.2.tgz#957155ebeb67a13164069825ce67ddb5bb2dd360" - integrity sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ== +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== dependencies: - colors "^1.2.1" - fast-safe-stringify "^2.0.4" - fecha "^2.3.3" - ms "^2.1.1" - triple-beam "^1.3.0" + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" -long@4.0.0: +long@4.0.0, long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== @@ -5369,38 +4717,40 @@ long@4.0.0: long@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" - integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= + integrity sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" + tslib "^2.0.3" -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= - -lowercase-keys@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" - integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= - -lowercase-keys@^1.0.0: +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^4.0.0: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5408,791 +4758,472 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -make-dir@^2.0.0, make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-error@1.x, make-error@^1.1.1: - version "1.3.5" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" - integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: - tmpl "1.0.x" + yallist "^4.0.0" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== +lru-cache@^9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.1.tgz#c58a93de58630b688de39ad04ef02ef26f1902f1" + integrity sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A== -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + semver "^6.0.0" -map-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" - integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= +make-error@1.x: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: - object-visit "^1.0.0" + tmpl "1.0.5" -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== +matcher@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca" + integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng== dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" + escape-string-regexp "^4.0.0" media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -memoize-one@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" - integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA== - -memory-fs@^0.4.0, memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -meow@^3.3.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - -meow@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" - integrity sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A== - dependencies: - camelcase-keys "^4.0.0" - decamelize-keys "^1.0.0" - loud-rejection "^1.0.0" - minimist "^1.1.3" - minimist-options "^3.0.1" - normalize-package-data "^2.3.4" - read-pkg-up "^3.0.0" - redent "^2.0.0" - trim-newlines "^2.0.0" - -meow@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" - integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== - dependencies: - camelcase-keys "^4.0.0" - decamelize-keys "^1.0.0" - loud-rejection "^1.0.0" - minimist-options "^3.0.1" - normalize-package-data "^2.3.4" - read-pkg-up "^3.0.0" - redent "^2.0.0" - trim-newlines "^2.0.0" - yargs-parser "^10.0.0" +memoize-one@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" + integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== +method-override@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/method-override/-/method-override-3.0.0.tgz#6ab0d5d574e3208f15b0c9cf45ab52000468d7a2" + integrity sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA== + dependencies: + debug "3.1.0" + methods "~1.1.2" + parseurl "~1.3.2" + vary "~1.1.2" + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== -micromatch@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== +micromatch@^4.0.0, micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" + braces "^3.0.2" + picomatch "^2.3.1" -mime-db@1.43.0: - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - mime-db "1.43.0" + mime-db "1.52.0" mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mimic-fn@^2.0.0: +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-response@^1.0.0: +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== -mimic-response@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.0.0.tgz#996a51c60adf12cb8a87d7fb8ef24c2f3d5ebb46" - integrity sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= - -minimatch@3.0.4, minimatch@^3.0.4: +minimatch@3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimist-options@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" - integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" + brace-expansion "^2.0.1" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= +minimatch@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.0.tgz#bfc8e88a1c40ffd40c172ddac3decb8451503b56" + integrity sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w== + dependencies: + brace-expansion "^2.0.1" minimist@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" - integrity sha1-md9lelJXTCHJBXSX33QnkLK0wN4= - -minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + integrity sha512-wR5Ipl99t0mTGwLjQJnBjrP/O7zBbLZqvA3aw32DmLx+nXHfWctUjzDjnDx09pX1Po86WFQazF9xUzfMea3Cnw== -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.5.1, mkdirp@0.x, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -mocha@^6.1.4: - version "6.2.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.2.tgz#5d8987e28940caf8957a7d7664b910dc5b2fea20" - integrity sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "2.2.0" - minimatch "3.0.4" - mkdirp "0.5.1" - ms "2.1.1" - node-environment-flags "1.0.5" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.0" - yargs-parser "13.1.1" - yargs-unparser "1.6.0" - -modify-values@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" - integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== +"minipass@^5.0.0 || ^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.1.tgz#315417c259cb32a1b2fc530c0e7f55c901a60a6d" + integrity sha512-Tenl5QPpgozlOGBiveNYHg2f6y+VpxsXRoIHFUVJuSmTonXRAE6q9b8Mp/O46762/2AlW4ye4Nkyvx0fgWDKbw== -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= +mkdirp@^0.5.4: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" + minimist "^1.2.6" ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== ms@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@^2.1.1: +ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +nanotimer@^0.3.15: + version "0.3.15" + resolved "https://registry.yarnpkg.com/nanotimer/-/nanotimer-0.3.15.tgz#280d277db9146eca6f8a570b572abaf2a9acc754" + integrity sha512-xj8HcwceqeRbfSuwNIzYhdbyZu3zoiHX3y2cyVB/cLn0RzVCI8ZZVQLZELEUMG2tYEsjqbCLb3b4q1lDC7ENnA== natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== +neo-async@^2.6.0, neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -nlf@^1.4.2: - version "1.4.3" - resolved "https://registry.yarnpkg.com/nlf/-/nlf-1.4.3.tgz#3e8370a0bd0d1758b97d49d69d79bdcd0d1d113d" - integrity sha1-PoNwoL0NF1i5fUnWnXm9zQ0dET0= +nlf@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nlf/-/nlf-2.1.1.tgz#73189d4c7f8a0d9f46de501a1a7aff880882b959" + integrity sha512-ysGGIax/WydhF78a5k//FPMt9tVDVLsnuSZqxwuzIfc5waKKc0Y/jz082a81aAayrP1QQNQm5ck+5Kv+jlbU6Q== dependencies: archy "1.0.0" - commander "2.9.0" - compare-versions "3.0.0" - glob-all "3.1.0 " - read-installed "4.0.3" + commander "2.19.0" + compare-versions "3.4.0" + glob-all "3.1.0" + snyk-resolve-deps "4.0.2" -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== - dependencies: - lower-case "^1.1.1" - -node-environment-flags@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" - integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + lower-case "^2.0.2" + tslib "^2.0.3" -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - -node-license-validator@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/node-license-validator/-/node-license-validator-1.3.0.tgz#c49d3399ccb6087605a4464e9716d8242a36f454" - integrity sha1-xJ0zmcy2CHYFpEZOlxbYJCo29FQ= - dependencies: - nlf "^1.4.2" - npm-package-arg "^4.2.0" - semver "^4.3.6" - spdx-expression-validate "^1.0.1" - spdx-satisfies "^0.1.3" - yargs "^3.32.0" +node-addon-api@^1.6.3: + version "1.7.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d" + integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== -node-notifier@^5.4.2: - version "5.4.3" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" - integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== - dependencies: - growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" - shellwords "^0.1.1" - which "^1.3.0" +node-emberplus@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/node-emberplus/-/node-emberplus-3.0.5.tgz#a87d1f6de0034cf285ca166722f7f9cf8ab573c1" + integrity sha512-PVnPNKpYoJ72ga8QZ40Cv3h5mmbDuZ7JbHpWu6x8FvVQ4H3cu4NLeqx1l3b8bxCVz8NmbE+3yuoRvC03wQhMfw== + dependencies: + "@types/asn1" "^0.2.0" + "@types/long" "^4.0.0" + "@types/safer-buffer" "2.1.0" + gdnet-asn1 "1.0.0" + long "^4.0.0" + reflect-metadata "0.1.13" + smart-buffer "^3.0.3" + typedi "0.8.0" + winston "^2.1.1" + winston-color "^1.0.0" + yargs "^17.5.1" -node-releases@^1.1.44: - version "1.1.44" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.44.tgz#cd66438a6eb875e3eb012b6a12e48d9f4326ffd7" - integrity sha512-NwbdvJyR7nrcGrXvKAvzc5raj/NkoJudkarh2yIpJ4t0NH4aqjUDz/486P+ynIW5eokKOfzGNRdYoLfBlomruw== - dependencies: - semver "^6.3.0" +node-gyp-build@^4.3.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" + integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== -normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= +node-license-validator@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/node-license-validator/-/node-license-validator-1.3.2.tgz#c7884596e3ec107cae6ee0a94a86a4149c98b77b" + integrity sha512-pw6eXdzPkY6+NLeFQA1dUSZ14m9ovjbBq3MaEFfFZgFdJtIjfhoiM7i9BhXV6dQcEN5mD34k8Ry+mYuri48tXg== + dependencies: + nlf "^2.1.1" + npm-package-arg "^8.1.5" + semver "^7.3.5" + spdx-expression-validate "^2.0.0" + spdx-satisfies "^5.0.1" + yargs "^17.0.1" + +node-releases@^2.0.8: + version "2.0.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== + +node-vmix@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/node-vmix/-/node-vmix-1.6.1.tgz#d9cc5bedede8e7d55f4f9d88967e2565e1ae5fd3" + integrity sha512-ivfB579jh4cGnSpygpIvYBB1hjuFpSqUVFa2U1Oua73KJKS0jIN6kAiBnQFnCU68o+WWEnFa5Ag/u8xKoBSqRw== dependencies: - remove-trailing-separator "^1.0.1" + axios "^0.27.2" + querystring "^0.2.1" normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" - integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== - dependencies: - prepend-http "^2.0.0" - query-string "^5.0.1" - sort-keys "^2.0.0" +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== -nouislider-react@^3.3.7: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nouislider-react/-/nouislider-react-3.3.7.tgz#4efbeb8a2407b990154e5a6819840f6752af0d58" - integrity sha512-vC2r66CAQrQCWmGXX8KTCy7uf/DnFN+z08brm9Yke9WiWTs9TXMlmjCj+vMbUXgLEyI3nDtAyScraoOBuqlmag== +nouislider-react@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/nouislider-react/-/nouislider-react-3.4.1.tgz#cb0fc3d77ed8f7818cf52b614f0d67f3e16275d4" + integrity sha512-ryVbcApz6sELqPPiWwEOq5pkwhHYoNSxmGpP/HXHptpB6A6XedMrM/BP5W/rHRtBBaFK7vJTCTTma6gKviEiNg== dependencies: - nouislider "^14.1.1" + nouislider "^14.6.3" -nouislider@^14.1.1: - version "14.1.1" - resolved "https://registry.yarnpkg.com/nouislider/-/nouislider-14.1.1.tgz#def812b2aaaa2ccf9e7a41dd0144a25dab5673e5" - integrity sha512-3/+Z/pTBoWoJf2YXSEWRmS27LW2XxOBmGEzkPyRzB/J6QvL+0mS3QwcQp0SmWhgO5CMzbSxPmb1lDDD4HP12bg== +nouislider@^14.6.3: + version "14.7.0" + resolved "https://registry.yarnpkg.com/nouislider/-/nouislider-14.7.0.tgz#a71db0587c92567b6da1df57d251d3696d942362" + integrity sha512-4RtQ1+LHJKesDCNJrXkQcwXAWCrC2aggdLYMstS/G5fEWL+fXZbUA9pwVNHFghMGuFGRATlDLNInRaPeRKzpFQ== -npm-normalize-package-bin@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== +nouislider@^15.7.0: + version "15.7.0" + resolved "https://registry.yarnpkg.com/nouislider/-/nouislider-15.7.0.tgz#3d8ec43c6f767ceb7f17afc555016ef907cedc3d" + integrity sha512-aJVEULBPOUwq32/s7xnLNyLvo4kuzYJJsNp2PNGW932AQ0uuDAbLShAqswtxRzJc5n/dLJXNlYSLOZ57bcUg1w== -npm-package-arg@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.2.1.tgz#593303fdea85f7c422775f17f9eb7670f680e3ec" - integrity sha1-WTMD/eqF98Qid18X+et2cPaA4+w= +npm-conf@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== dependencies: - hosted-git-info "^2.1.5" - semver "^5.1.0" + config-chain "^1.1.11" + pify "^3.0.0" -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= +npm-package-arg@^8.1.5: + version "8.1.5" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" + integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== dependencies: - path-key "^2.0.0" + hosted-git-info "^4.0.1" + semver "^7.3.4" + validate-npm-package-name "^3.0.0" -nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: - boolbase "~1.0.0" - -null-check@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" - integrity sha1-l33/1xdgErnsMNKjnbXPcqBDnt0= + path-key "^3.0.0" -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" -nwsapi@^2.0.7: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== +npmlog@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-component@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" - integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== +object-inspect@^1.12.3, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@4.1.0, object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.getownpropertydescriptors@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== dependencies: ee-first "1.1.1" +on-headers@~1.0.1, on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" -one-time@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e" - integrity sha1-+M33eISCb+Tf+T46nMN7HkSAdC4= - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: - lcid "^1.0.0" + mimic-fn "^2.1.0" -os-locale@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" + mimic-fn "^4.0.0" -"osc@https://github.com/olzzon/tv2-osc.js-no-serialport.git": - version "2.3.1" - resolved "https://github.com/olzzon/tv2-osc.js-no-serialport.git#2e5df73f13409a1d9eee1f4079dae8490c684852" +osc@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/osc/-/osc-2.4.4.tgz#52b2e914253b04a792d28ee892b0fa1ca8bdc1a2" + integrity sha512-YJr2bUCQMc9BIaq1LXgqYpt5Ii7wNy2n0e0BkQiCSziMNrrsYHhH5OlExNBgCrQsum60EgXZ32lFsvR4aUf+ew== dependencies: - fastestsmallesttextencoderdecoder "^1.0.7" long "4.0.0" slip "1.0.2" - wolfy87-eventemitter "5.2.6" - ws "7.0.0" - -p-cancelable@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" - integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + wolfy87-eventemitter "5.2.9" + ws "8.13.0" + optionalDependencies: + serialport "10.5.0" -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= - dependencies: - p-reduce "^1.0.0" +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" - integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== -p-is-promise@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-3.0.0.tgz#58e78c7dfe2e163cf2a04ff869e7c1dba64a5971" - integrity sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== - dependencies: - p-try "^2.0.0" +p-lazy@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-lazy/-/p-lazy-3.1.0.tgz#4b1e40482b7ee87853abbcf31824ff64e1816d61" + integrity sha512-sCJn0Cdahs6G6SX9+DUihVFUhrzDEduzE5xeViVBGtoqy5dBWko7W8T6Kk6TjR2uevRXJO7CShfWrqdH5s3w3g== -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: - p-limit "^1.1.0" + p-try "^2.0.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== +p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: - p-limit "^2.0.0" + yocto-queue "^0.1.0" p-locate@^4.1.0: version "4.1.0" @@ -6201,48 +5232,50 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" -p-timeout@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" - integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== +p-queue@^6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" + integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== dependencies: - p-finally "^1.0.0" + eventemitter3 "^4.0.4" + p-timeout "^3.2.0" -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= +p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pako@~1.0.5: - version "1.0.10" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" - integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== - -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" -param-case@2.1.x: - version "2.1.1" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== dependencies: - no-case "^2.2.0" + dot-case "^3.0.4" + tslib "^2.0.3" parent-module@^1.0.0: version "1.0.1" @@ -6251,113 +5284,28 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-asn1@^5.0.0: - version "5.1.5" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" - integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== - dependencies: - asn1.js "^4.0.0" - browserify-aes "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - -parse-domain@2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/parse-domain/-/parse-domain-2.1.8.tgz#edf9e47236d397c0a6ea043dddb116c83cf22099" - integrity sha512-k5Qcem1wNuCp+thb48MHmje78iRnJjPkT9XK9ybjyGDqGnVV4ty4BowRs8kB3HHpcKgDrgQ0ewHEZB+zFQM/dQ== - dependencies: - chai "^4.2.0" - got "^8.3.2" - mkdirp "^0.5.1" - mocha "^6.1.4" - -parse-github-repo-url@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" - integrity sha1-nn2LslKmy2ukJZUGC3v23z28H1A= - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" - integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== +parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" + json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= - -parse5@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" - integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== - -parseqs@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" - integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= - dependencies: - better-assert "~1.0.0" - -parseuri@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" - integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= - dependencies: - better-assert "~1.0.0" - -parseurl@~1.3.3: +parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + no-case "^3.0.4" + tslib "^2.0.3" path-exists@^4.0.0: version "4.0.0" @@ -6367,286 +5315,341 @@ path-exists@^4.0.0: path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.7.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.9.1.tgz#838566bb22e38feaf80ecd49ae06cd12acd782ee" + integrity sha512-UgmoiySyjFxP6tscZDgWGEAgsW5ok8W3F5CJDnnH2pozwSTGE6eH7vwTotMwATWA2r5xqdkKdxYPkwlJjAI/3g== + dependencies: + lru-cache "^9.1.1" + minipass "^5.0.0 || ^6.0.0" path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" +path-to-regexp@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" + integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pathval@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" - integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= - -pbkdf2@^3.0.3: - version "3.0.17" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" - integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== -picomatch@^2.0.5: - version "2.2.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" - integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pidtree@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" + integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: - pinkie "^2.0.0" + find-up "^4.0.0" -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pirates@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== +pkg-prebuilds@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/pkg-prebuilds/-/pkg-prebuilds-0.2.1.tgz#4b91f410ab600df4eb657634d623549cc188c5ed" + integrity sha512-FdOlDiRqRL7i9aYzQflhGWCoiJf/8u6Qgzq48gKsRDYejtfjvGb1U5QGSzllcqpNg2a8Swx/9fMgtuVefwU+zw== dependencies: - node-modules-regexp "^1.0.0" + yargs "^17.5.1" -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== +plist@^3.0.1, plist@^3.0.4: + version "3.0.6" + resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.6.tgz#7cfb68a856a7834bca6dbfe3218eb9c7740145d3" + integrity sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA== dependencies: - find-up "^3.0.0" - -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + base64-js "^1.5.1" + xmlbuilder "^15.1.1" -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== - dependencies: - postcss "^7.0.5" +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== -postcss-modules-local-by-default@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" - integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ== +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== dependencies: - icss-utils "^4.1.1" - postcss "^7.0.16" + icss-utils "^5.0.0" postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.0" + postcss-value-parser "^4.1.0" -postcss-modules-scope@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.1.tgz#33d4fc946602eb5e9355c4165d68a10727689dba" - integrity sha512-OXRUPecnHCg8b9xWvldG/jUpRIGPNRka0r4D4j0ESUU2/5IOnpsjfPPmDprM3Ih8CgZ8FXjWqaniK5v4rWt3oQ== +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" + postcss-selector-parser "^6.0.4" -postcss-modules-values@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" - integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== dependencies: - icss-utils "^4.0.0" - postcss "^7.0.6" + icss-utils "^5.0.0" -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" - integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== dependencies: cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" + util-deprecate "^1.0.2" -postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" - integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.23, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.26" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.26.tgz#5ed615cfcab35ba9bbb82414a4fa88ea10429587" - integrity sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA== +postcss@^8.4.19: + version "8.4.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab" + integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA== dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" prepend-http@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== -pretty-error@^2.0.2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" - integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= - dependencies: - renderkid "^2.0.1" - utila "~0.4" +prettier@^2.8.8: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== -pretty-format@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" - integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== +pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== dependencies: - "@jest/types" "^24.9.0" - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - react-is "^16.8.4" + lodash "^4.17.20" + renderkid "^3.0.0" -private@^0.1.6: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== +pretty-format@^29.0.0, pretty-format@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" + integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== + dependencies: + "@jest/schemas" "^29.4.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +progress@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/promise-fs/-/promise-fs-2.1.1.tgz#0b725a592c165ff16157d1f13640ba390637e557" + integrity sha512-43p7e4QzAQ3w6eyN0+gbBL7jXiZFWLWYITg9wIObqkBySu/a5K1EDcQ/S6UyB/bmiZWDA4NjTbcopKLTaKcGSw== + dependencies: + "@octetstream/promisify" "2.0.2" -promise@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.0.3.tgz#f592e099c6cddc000d538ee7283bb190452b0bf6" - integrity sha512-HeRDUL1RJiLhyA0/grn+PTShlBAcLuh/1BJGtrvjwbvRDCTLLMEz9rOGCV+R3vHY4MixIuoMEd9Yq/XvsTPcjw== +"promise@>=3.2 <8", promise@^7.0.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== dependencies: - asap "~2.0.6" + asap "~2.0.3" prompts@^2.0.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.0.tgz#a444e968fa4cc7e86689a74050685ac8006c4cc4" - integrity sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg== + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: kleur "^3.0.3" - sisteransi "^1.0.3" + sisteransi "^1.0.5" -prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== +prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== dependencies: loose-envify "^1.4.0" object-assign "^4.1.1" - react-is "^16.8.1" + react-is "^16.13.1" -proxy-addr@~2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" - integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ== +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.0" + forwarded "0.2.0" + ipaddr.js "1.9.1" -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== -psl@^1.1.24, psl@^1.1.28: - version "1.7.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" - integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== +pug-attrs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41" + integrity sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA== dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" + constantinople "^4.0.1" + js-stringify "^1.0.2" + pug-runtime "^3.0.0" + +pug-code-gen@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-3.0.2.tgz#ad190f4943133bf186b60b80de483100e132e2ce" + integrity sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg== + dependencies: + constantinople "^4.0.1" + doctypes "^1.1.0" + js-stringify "^1.0.2" + pug-attrs "^3.0.0" + pug-error "^2.0.0" + pug-runtime "^3.0.0" + void-elements "^3.1.0" + with "^7.0.0" + +pug-error@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.0.0.tgz#5c62173cb09c34de2a2ce04f17b8adfec74d8ca5" + integrity sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ== + +pug-filters@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-4.0.0.tgz#d3e49af5ba8472e9b7a66d980e707ce9d2cc9b5e" + integrity sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A== + dependencies: + constantinople "^4.0.1" + jstransformer "1.0.0" + pug-error "^2.0.0" + pug-walk "^2.0.0" + resolve "^1.15.1" + +pug-lexer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.1.tgz#ae44628c5bef9b190b665683b288ca9024b8b0d5" + integrity sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w== + dependencies: + character-parser "^2.2.0" + is-expression "^4.0.0" + pug-error "^2.0.0" + +pug-linker@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-4.0.0.tgz#12cbc0594fc5a3e06b9fc59e6f93c146962a7708" + integrity sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw== + dependencies: + pug-error "^2.0.0" + pug-walk "^2.0.0" + +pug-load@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-3.0.0.tgz#9fd9cda52202b08adb11d25681fb9f34bd41b662" + integrity sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ== + dependencies: + object-assign "^4.1.1" + pug-walk "^2.0.0" + +pug-parser@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-6.0.0.tgz#a8fdc035863a95b2c1dc5ebf4ecf80b4e76a1260" + integrity sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw== + dependencies: + pug-error "^2.0.0" + token-stream "1.0.0" + +pug-runtime@^3.0.0, pug-runtime@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-3.0.1.tgz#f636976204723f35a8c5f6fad6acda2a191b83d7" + integrity sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg== + +pug-strip-comments@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz#f94b07fd6b495523330f490a7f554b4ff876303e" + integrity sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ== + dependencies: + pug-error "^2.0.0" + +pug-walk@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-2.0.0.tgz#417aabc29232bb4499b5b5069a2b2d2a24d5f5fe" + integrity sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ== + +pug@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pug/-/pug-3.0.2.tgz#f35c7107343454e43bc27ae0ff76c731b78ea535" + integrity sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw== + dependencies: + pug-code-gen "^3.0.2" + pug-filters "^4.0.0" + pug-lexer "^5.0.1" + pug-linker "^4.0.0" + pug-load "^3.0.0" + pug-parser "^6.0.0" + pug-runtime "^3.0.1" + pug-strip-comments "^2.0.0" pump@^3.0.0: version "3.0.0" @@ -6656,263 +5659,211 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^1.2.4, punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== -punycode@^2.1.0, punycode@^2.1.1: +pupa@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -q@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== + dependencies: + escape-goat "^2.0.0" -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +pure-rand@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" + integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== +qs@^6.11.0: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" + side-channel "^1.0.4" -querystring-es3@^0.2.0: +querystring@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" + integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== -quick-lru@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" - integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + integrity sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ== -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: +randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== dependencies: - bytes "3.1.0" - http-errors "1.7.2" + bytes "3.1.2" + http-errors "2.0.0" iconv-lite "0.4.24" unpipe "1.0.0" -react-dom@^16.10.1: - version "16.12.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11" - integrity sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw== +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.18.0" + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" -react-input-autosize@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.2.tgz#fcaa7020568ec206bc04be36f4eb68e647c4d8c2" - integrity sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw== +rc@1.2.8, rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: - prop-types "^15.5.8" - -react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: - version "16.12.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" - integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== - -react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" -react-redux@^7.1.1: - version "7.1.3" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.1.3.tgz#717a3d7bbe3a1b2d535c94885ce04cdc5a33fc79" - integrity sha512-uI1wca+ECG9RoVkWQFF4jDMqmaw0/qnvaSvOoL/GA4dNxf6LoV8sUAcNDvE5NWKs4hFpn0t6wswNQnY3f7HT3w== +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== dependencies: - "@babel/runtime" "^7.5.5" - hoist-non-react-statics "^3.3.0" - invariant "^2.2.4" - loose-envify "^1.4.0" - prop-types "^15.7.2" - react-is "^16.9.0" - -react-select@^3.0.6: - version "3.0.8" - resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.0.8.tgz#06ff764e29db843bcec439ef13e196865242e0c1" - integrity sha512-v9LpOhckLlRmXN5A6/mGGEft4FMrfaBFTGAnuPHcUgVId7Je42kTq9y0Z+Ye5z8/j0XDT3zUqza8gaRaI1PZIg== - dependencies: - "@babel/runtime" "^7.4.4" - "@emotion/cache" "^10.0.9" - "@emotion/core" "^10.0.9" - "@emotion/css" "^10.0.9" - memoize-one "^5.0.0" + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-draggable@^4.4.5: + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.5.tgz#9e37fe7ce1a4cf843030f521a0a4cc41886d7e7c" + integrity sha512-OMHzJdyJbYTZo4uQE393fHcqqPYsEtkjfMgvCHr6rejT+Ezn4OZbNyGH50vv+SunC1RMvwOTSWkEODQLzw1M9g== + dependencies: + clsx "^1.1.1" + prop-types "^15.8.1" + +react-i18next@^12.2.2: + version "12.2.2" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-12.2.2.tgz#38a6fad11acf4f2abfc5611bdb6b1918d0f47578" + integrity sha512-KBB6buBmVKXUWNxXHdnthp+38gPyBT46hJCAIQ8rX19NFL/m2ahte2KARfIDf2tMnSAL7wwck6eDOd/9zn6aFg== + dependencies: + "@babel/runtime" "^7.20.6" + html-parse-stringify "^3.0.1" + +"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0, react-is@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-redux@^8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.5.tgz#e5fb8331993a019b8aaf2e167a93d10af469c7bd" + integrity sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw== + dependencies: + "@babel/runtime" "^7.12.1" + "@types/hoist-non-react-statics" "^3.3.1" + "@types/use-sync-external-store" "^0.0.3" + hoist-non-react-statics "^3.3.2" + react-is "^18.0.0" + use-sync-external-store "^1.0.0" + +react-select@^5.7.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.7.3.tgz#fa0dc9a23cad6ff3871ad3829f6083a4b54961a2" + integrity sha512-z8i3NCuFFWL3w27xq92rBkVI2onT0jzIIPe480HlBjXJ3b5o6Q+Clp4ydyeKrj9DZZ3lrjawwLC5NGl0FSvUDg== + dependencies: + "@babel/runtime" "^7.12.0" + "@emotion/cache" "^11.4.0" + "@emotion/react" "^11.8.1" + "@floating-ui/dom" "^1.0.1" + "@types/react-transition-group" "^4.4.0" + memoize-one "^6.0.0" prop-types "^15.6.0" - react-input-autosize "^2.2.2" - react-transition-group "^2.2.1" - -react-slider@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/react-slider/-/react-slider-1.0.2.tgz#066e61ce5cfd7983dbee735971204f541f382d79" - integrity sha512-fl2qPKa5+z1YQ94H74xcB8JEyaxjQJQN4ZAVD+pfX/CN4tMdQwMDjB8Y2XmvVK4BjMwoYFaLG8zFKC4oHNcuGQ== - -react-test-renderer@^16.11.0: - version "16.12.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.12.0.tgz#11417ffda579306d4e841a794d32140f3da1b43f" - integrity sha512-Vj/teSqt2oayaWxkbhQ6gKis+t5JrknXfPVo+aIJ8QwYAqMPH77uptOdrlphyxl8eQI/rtkOYg86i/UWkpFu0w== - dependencies: - object-assign "^4.1.1" - prop-types "^15.6.2" - react-is "^16.8.6" - scheduler "^0.18.0" - -react-transition-group@^2.2.1: - version "2.9.0" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" - integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== - dependencies: - dom-helpers "^3.4.0" - loose-envify "^1.4.0" - prop-types "^15.6.2" - react-lifecycles-compat "^3.0.4" + react-transition-group "^4.3.0" + use-isomorphic-layout-effect "^1.1.2" -react@^16.10.1: - version "16.12.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83" - integrity sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA== +react-shallow-renderer@^16.15.0: + version "16.15.0" + resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457" + integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA== dependencies: - loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.2" + react-is "^16.12.0 || ^17.0.0 || ^18.0.0" -reactjs-popup@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/reactjs-popup/-/reactjs-popup-1.5.0.tgz#09ef15daf9bf932e9adbf595f3976851c24913cf" - integrity sha512-9uoxUAcUomnNoBtdYXBmgsF4w46llsogE3tOvLb5IkR5MMrD6UZJK20ip9kDKXCYubSxNkdfQKqSb/c95rf/qA== - -read-installed@4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" - integrity sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc= - dependencies: - debuglog "^1.0.1" - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - semver "2 || 3 || 4 || 5" - slide "~1.1.3" - util-extend "^1.0.1" - optionalDependencies: - graceful-fs "^4.1.2" - -read-package-json@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.1.tgz#16aa66c59e7d4dad6288f179dd9295fd59bb98f1" - integrity sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A== +react-slider@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/react-slider/-/react-slider-2.0.4.tgz#21c656ffabc3bb4481cf6b49e6d647baeda83572" + integrity sha512-sWwQD01n6v+MbeLCYthJGZPc0kzOyhQHyd0bSo0edg+IAxTVQmj3Oy4SBK65eX6gNwS9meUn6Z5sIBUVmwAd9g== dependencies: - glob "^7.1.1" - json-parse-better-errors "^1.0.1" - normalize-package-data "^2.0.0" - npm-normalize-package-bin "^1.0.0" - optionalDependencies: - graceful-fs "^4.1.2" + prop-types "^15.8.1" -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= +react-test-renderer@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.2.0.tgz#1dd912bd908ff26da5b9fca4fd1c489b9523d37e" + integrity sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA== dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" + react-is "^18.2.0" + react-shallow-renderer "^16.15.0" + scheduler "^0.23.0" -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= +react-transition-group@^4.3.0: + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" + integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" + loose-envify "^1.1.0" -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" +reactjs-popup@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/reactjs-popup/-/reactjs-popup-2.0.5.tgz#588a74966bb126699429d739948e3448d7771eac" + integrity sha512-b5hv9a6aGsHEHXFAgPO5s1Jw1eSkopueyUVxQewGdLgqk2eW0IVXZrPRpHR629YcgIpC2oxtX8OOZ8a7bQJbxA== -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= +read-config-file@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-6.2.0.tgz#71536072330bcd62ba814f91458b12add9fc7ade" + integrity sha512-gx7Pgr5I56JtYz+WuqEbQHj/xWo+5Vwua2jhb1VwM4Wid5PqYmZ4i00ZB0YEGIfkVBsCv9UrjgyqCiQfS/Oosg== dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" + dotenv "^9.0.2" + dotenv-expand "^5.1.0" + js-yaml "^4.1.0" + json5 "^2.2.0" + lazy-val "^1.0.4" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== +readable-stream@^2.2.2: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -6922,881 +5873,758 @@ read-pkg@^3.0.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" -"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.1.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" - integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdir-scoped-modules@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" - integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== - dependencies: - debuglog "^1.0.1" - dezalgo "^1.0.0" - graceful-fs "^4.1.2" - once "^1.3.0" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -realpath-native@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" - integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== - dependencies: - util.promisify "^1.0.0" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -redent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" - integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= - dependencies: - indent-string "^3.0.0" - strip-indent "^2.0.0" - -redux@^4.0.0, redux@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" - integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== - dependencies: - loose-envify "^1.4.0" - symbol-observable "^1.2.0" - -regenerate-unicode-properties@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== +readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== - -regenerator-runtime@^0.13.2: - version "0.13.3" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" - integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" -regenerator-transform@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb" - integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ== +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== dependencies: - private "^0.1.6" + resolve "^1.20.0" -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== -regexpu-core@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" - integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.1.0" - regjsgen "^0.5.0" - regjsparser "^0.6.0" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" - -regjsgen@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" - integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== + redis-errors "^1.0.0" -regjsparser@^0.6.0: - version "0.6.2" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.2.tgz#fd62c753991467d9d1ffe0a9f67f27a529024b96" - integrity sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q== +redux@^4.1.2, redux@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197" + integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== dependencies: - jsesc "~0.5.0" + "@babel/runtime" "^7.9.2" -relateurl@0.2.x: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= +reflect-metadata@0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -renderkid@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" - integrity sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA== +registry-auth-token@^4.0.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.2.tgz#f02d49c3668884612ca031419491a13539e21fac" + integrity sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg== dependencies: - css-select "^1.1.0" - dom-converter "^0.2" - htmlparser2 "^3.3.0" - strip-ansi "^3.0.0" - utila "^0.4.0" - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + rc "1.2.8" -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== dependencies: - is-finite "^1.0.0" + rc "^1.2.8" -request-promise-core@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" - integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== - dependencies: - lodash "^4.17.15" +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== -request-promise-native@^1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" - integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== - dependencies: - request-promise-core "1.1.3" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.87.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-dir@^1.0.0, resolve-dir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= - dependencies: - expand-tilde "^2.0.0" - global-modules "^1.0.0" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== -resolve-from@^3.0.0: +resolve-cwd@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + +resolve@^1.15.1, resolve@^1.19.0, resolve@^1.20.0: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" -resolve@1.x, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.3.2: - version "1.14.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.14.2.tgz#dbf31d0fa98b1f29aa5169783b9c290cb865fea2" - integrity sha512-EjlOBLBO1kxsUxsKjLt7TAECyKW6fOh1VRkykQkKGzcBbjjPIxBqGh0jf7GJ3k/f5mxMqW3htMD3WdTUVtW8HQ== +response-time@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/response-time/-/response-time-2.3.2.tgz#ffa71bab952d62f7c1d49b7434355fbc68dffc5a" + integrity sha512-MUIDaDQf+CVqflfTdQ5yam+aYCkXj1PY8fjlPDQ6ppxJlmgZb864pHtA750mayywNg8tx4rS7qH9JXd/OF+3gw== dependencies: - path-parse "^1.0.6" + depd "~1.1.0" + on-headers "~1.0.1" -responselike@1.0.2: +responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== dependencies: lowercase-keys "^1.0.0" -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^2.5.4, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== +rimraf@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.0.tgz#5bda14e410d7e4dd522154891395802ce032c2cb" + integrity sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g== dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" + glob "^10.0.0" -rsvp@^4.8.4: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== +rndm@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c" + integrity sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw== -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= +roarr@^2.15.3: + version "2.15.4" + resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd" + integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A== dependencies: - aproba "^1.1.1" + boolean "^3.0.1" + detect-node "^2.0.4" + globalthis "^1.0.1" + json-stringify-safe "^5.0.1" + semver-compare "^1.0.0" + sprintf-js "^1.1.2" + +rxjs@^7.8.0: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +safe-buffer@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" +safe-buffer@5.2.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" +sanitize-filename@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378" + integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg== + dependencies: + truncate-utf8-bytes "^1.0.0" sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4" - integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ== +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" -schema-utils@^1.0.0: +schema-utils@^3.1.1, schema-utils@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.2.tgz#36c10abca6f7577aeae136c804b0c741edeadc99" + integrity sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +semver-compare@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== + +semver-diff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" + integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" + semver "^6.3.0" -schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.1.tgz#eb78f0b945c7bcfa2082b3565e8db3548011dc4f" - integrity sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg== +semver@7.x, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.8: + version "7.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" + integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== dependencies: - ajv "^6.10.2" - ajv-keywords "^3.4.1" + lru-cache "^6.0.0" -"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0: +semver@^5.5.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@6.3.0, semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - -semver@^4.3.6: - version "4.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" - integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== dependencies: debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" + 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 "~1.7.2" + http-errors "2.0.0" mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" + ms "2.1.3" + on-finished "2.4.1" range-parser "~1.2.1" - statuses "~1.5.0" + statuses "2.0.1" -serialize-javascript@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" - integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== +serialize-error@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18" + integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw== + dependencies: + type-fest "^0.13.1" -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== +serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + +serialport@10.5.0: + version "10.5.0" + resolved "https://registry.yarnpkg.com/serialport/-/serialport-10.5.0.tgz#b85f614def6e8914e5865c798b0555330903a0f8" + integrity sha512-7OYLDsu5i6bbv3lU81pGy076xe0JwpK6b49G6RjNvGibstUqQkI+I3/X491yBGtf4gaqUdOgoU1/5KZ/XxL4dw== + dependencies: + "@serialport/binding-mock" "10.2.2" + "@serialport/bindings-cpp" "10.8.0" + "@serialport/parser-byte-length" "10.5.0" + "@serialport/parser-cctalk" "10.5.0" + "@serialport/parser-delimiter" "10.5.0" + "@serialport/parser-inter-byte-timeout" "10.5.0" + "@serialport/parser-packet-length" "10.5.0" + "@serialport/parser-readline" "10.5.0" + "@serialport/parser-ready" "10.5.0" + "@serialport/parser-regex" "10.5.0" + "@serialport/parser-slip-encoder" "10.5.0" + "@serialport/parser-spacepacket" "10.5.0" + "@serialport/stream" "10.5.0" + debug "^4.3.3" + +serve-favicon@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" + integrity sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA== + dependencies: + etag "~1.8.1" + fresh "0.5.2" + ms "2.1.1" + parseurl "~1.3.2" + safe-buffer "5.1.1" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.17.1" + send "0.18.0" + +server@^1.0.38: + version "1.0.38" + resolved "https://registry.yarnpkg.com/server/-/server-1.0.38.tgz#055232a3bcc69334099804b45f7a69e1284ee4da" + integrity sha512-RMpuql7HedxgfjqnQqUs8kt1LgkZRRyQaS2KOpsjRwo5bycxtePlwn1Qo/+/KEc33CFhvZflkLKZKdWU/lIWXw== + dependencies: + body-parser "^1.20.1" + compression "^1.7.4" + connect-redis "^6.1.3" + cookie-parser "^1.4.6" + csurf "^1.11.0" + dotenv "^16.0.3" + express "^4.18.1" + express-session "^1.17.3" + extend "^3.0.2" + hbs "^4.2.0" + helmet "^6.0.0" + ioredis "^5.2.3" + loadware "^2.0.0" + method-override "^3.0.0" + mz "^2.7.0" + npmlog "^6.0.2" + path-to-regexp "^6.2.1" + pug "^3.0.2" + response-time "^2.3.2" + serve-favicon "^2.5.0" + serve-index "^1.9.1" + socket.io "^4.5.2" + upload-files-express "^0.4.0" set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== setprototypeof@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" + kind-of "^6.0.2" -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= +"shared@file:shared": + version "0.0.0" dependencies: - shebang-regex "^1.0.0" + redux "^4.2.1" -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +shell-quote@^1.8.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: - is-arrayish "^0.3.1" + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" -sisteransi@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.4.tgz#386713f1ef688c7c0304dc4c0632898941cad2e3" - integrity sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig== +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +signal-exit@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== -slide@~1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" slip@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/slip/-/slip-1.0.2.tgz#ba45a923034d6cf41b1a27aebe7128282c8d551f" - integrity sha1-ukWpIwNNbPQbGieuvnEoKCyNVR8= + integrity sha512-XrcHe3NAcyD3wO+O4I13RcS4/3AF+S9RvGNj9JhJeS02HyImwD2E3QWLrmn9hBfL+fB6yapagwxRkeyYzhk98g== smart-buffer@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-3.0.3.tgz#76d4abf863d6aa91d5c9fd694cd51b242782e59f" - integrity sha1-dtSr+GPWqpHVyf1pTNUbJCeC5Z8= + integrity sha512-s5+gEstGAW315m+SbWCVjhf0+YZxqaeP6DieqzoHTHKghjyn0PhNhmR2qsqNNBaj8bBrwjmuxhXVKrGZqGphXQ== dependencies: "@types/node" "^7.0.4" -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== +smart-buffer@^4.0.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +snyk-module@^1.6.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/snyk-module/-/snyk-module-1.9.1.tgz#b2a78f736600b0ab680f1703466ed7309c980804" + integrity sha512-A+CCyBSa4IKok5uEhqT+hV/35RO6APFNLqk9DRRHg7xW2/j//nPX8wTSZUPF8QeRNEk/sX+6df7M1y6PBHGSHA== dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" + debug "^3.1.0" + hosted-git-info "^2.7.1" -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -socket.io-adapter@~1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9" - integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g== +snyk-resolve-deps@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/snyk-resolve-deps/-/snyk-resolve-deps-4.0.2.tgz#c3fa08a14fff6667628ec590061360de15f67ae6" + integrity sha512-nlw62wiWhGOTw3BD3jVIwrUkRR4iNxEkkO4Y/PWs8BsUWseGu1H6QgLesFXJb3qx7ANJ5UbUCJMgV+eL0Lf9cA== + dependencies: + ansicolors "^0.3.2" + debug "^3.2.5" + lodash.assign "^4.2.0" + lodash.assignin "^4.2.0" + lodash.clone "^4.5.0" + lodash.flatten "^4.4.0" + lodash.get "^4.4.2" + lodash.set "^4.3.2" + lru-cache "^4.0.0" + semver "^5.5.1" + snyk-module "^1.6.0" + snyk-resolve "^1.0.0" + snyk-tree "^1.0.0" + snyk-try-require "^1.1.1" + then-fs "^2.0.0" + +snyk-resolve@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/snyk-resolve/-/snyk-resolve-1.1.0.tgz#52740cb01ba477851086855f9857b3a44296ee0e" + integrity sha512-OZMF8I8TOu0S58Z/OS9mr8jkEzGAPByCsAkrWlcmZgPaE0RsxVKVIFPhbMNy/JlYswgGDYYIEsNw+e0j1FnTrw== + dependencies: + debug "^4.1.1" + promise-fs "^2.1.1" -socket.io-client@2.3.0, socket.io-client@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" - integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== - dependencies: - backo2 "1.0.2" - base64-arraybuffer "0.1.5" - component-bind "1.0.0" - component-emitter "1.2.1" - debug "~4.1.0" - engine.io-client "~3.4.0" - has-binary2 "~1.0.2" - has-cors "1.1.0" - indexof "0.0.1" - object-component "0.0.3" - parseqs "0.0.5" - parseuri "0.0.5" - socket.io-parser "~3.3.0" - to-array "0.1.4" - -socket.io-parser@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" - integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== +snyk-tree@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/snyk-tree/-/snyk-tree-1.0.0.tgz#0fb73176dbf32e782f19100294160448f9111cc8" + integrity sha512-JQezX6eaVi0uNctPcx2Uzy5KA9lpTRRe31n8NI71DIseGvI6OVCfuKjzFptE06h4ZISMey351ICXnHBadBtWdg== dependencies: - component-emitter "1.2.1" - debug "~3.1.0" - isarray "2.0.1" + archy "^1.0.0" -socket.io-parser@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.4.0.tgz#370bb4a151df2f77ce3345ff55a7072cc6e9565a" - integrity sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ== +snyk-try-require@^1.1.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/snyk-try-require/-/snyk-try-require-1.3.1.tgz#6e026f92e64af7fcccea1ee53d524841e418a212" + integrity sha512-adCnpfCvigiarbADOHuqh82P4aQUlyq6nWzhVmEUly62Q3tnVg4BGtgjYISkaj9GGBmpgVZiJegENBpQr02NsQ== dependencies: - component-emitter "1.2.1" - debug "~4.1.0" - isarray "2.0.1" + debug "^3.1.0" + lodash.clonedeep "^4.3.0" + lru-cache "^4.0.0" + then-fs "^2.0.0" -socket.io@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.3.0.tgz#cd762ed6a4faeca59bc1f3e243c0969311eb73fb" - integrity sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg== +socket.io-adapter@~2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz#5de9477c9182fdc171cd8c8364b9a8894ec75d12" + integrity sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA== dependencies: - debug "~4.1.0" - engine.io "~3.4.0" - has-binary2 "~1.0.2" - socket.io-adapter "~1.1.0" - socket.io-client "2.3.0" - socket.io-parser "~3.4.0" + ws "~8.11.0" -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= +socket.io-client@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.6.2.tgz#2bfde952e74625d54e622718a7cb1d591ee62fd6" + integrity sha512-OwWrMbbA8wSqhBAR0yoPK6EdQLERQAYjXb3A0zLpgxfM1ZGLKoxHx8gVmCHA6pcclRX5oA/zvQf7bghAS11jRA== dependencies: - is-plain-obj "^1.0.0" + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.2" + engine.io-client "~6.4.0" + socket.io-parser "~4.2.4" -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== +socket.io-parser@^4.2.3, socket.io-parser@~4.2.1, socket.io-parser@~4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83" + integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew== + dependencies: + "@socket.io/component-emitter" "~3.1.0" + debug "~4.3.1" + +socket.io@^4.5.2: + version "4.6.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.6.1.tgz#62ec117e5fce0692fa50498da9347cfb52c3bc70" + integrity sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.4.1" + socket.io-adapter "~2.5.2" + socket.io-parser "~4.2.1" -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== +socket.io@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.6.2.tgz#d597db077d4df9cbbdfaa7a9ed8ccc3d49439786" + integrity sha512-Vp+lSks5k0dewYTfwgPT9UeGGd+ht7sCpB7p0e83VgO4X/AHYWhXITMrNk/pg8syY2bpx23ptClCQuHhqi2BgQ== dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.4.2" + socket.io-adapter "~2.5.2" + socket.io-parser "~4.2.4" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-support@^0.5.6, source-map-support@~0.5.12: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= +source-map-support@^0.5.19, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" -source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: +source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -spdx-compare@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/spdx-compare/-/spdx-compare-0.1.2.tgz#b06af3ea34af7437d91a9f449eaf2d2e93c3c8fb" - integrity sha1-sGrz6jSvdDfZGp9Enq8tLpPDyPs= - dependencies: - spdx-expression-parse "^1.0.0" - spdx-ranges "^1.0.0" +spawn-command@0.0.2-1: + version "0.0.2-1" + resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" + integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg== -spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== +spdx-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/spdx-compare/-/spdx-compare-1.0.0.tgz#2c55f117362078d7409e6d7b08ce70a857cd3ed7" + integrity sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A== dependencies: + array-find-index "^1.0.2" spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" + spdx-ranges "^2.0.0" spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== - -spdx-expression-parse@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" - integrity sha1-m98vIOH0DtRH++JzJmGR/O1RYmw= + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" -spdx-expression-validate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-expression-validate/-/spdx-expression-validate-1.0.2.tgz#5a4e4d7616ed1c9b88150366b4217f767c27e9e3" - integrity sha1-Wk5NdhbtHJuIFQNmtCF/dnwn6eM= +spdx-expression-validate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz#25c9408e1c63fad94fff5517bb7101ffcd23350b" + integrity sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg== dependencies: - spdx-expression-parse "^1.0.0" + spdx-expression-parse "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== - -spdx-ranges@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/spdx-ranges/-/spdx-ranges-1.0.1.tgz#0f4eec7b8ea48ed202e374bb8942e8d18dc0113e" - integrity sha1-D07se46kjtIC43S7iULo0Y3AET4= + version "3.0.13" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== -spdx-satisfies@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/spdx-satisfies/-/spdx-satisfies-0.1.3.tgz#67a1f274e6115d4aae28afe474db76164be10bdc" - integrity sha1-Z6HydOYRXUquKK/kdNt2FkvhC9w= - dependencies: - spdx-compare "^0.1.2" - spdx-expression-parse "^1.0.0" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" +spdx-ranges@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/spdx-ranges/-/spdx-ranges-2.1.1.tgz#87573927ba51e92b3f4550ab60bfc83dd07bac20" + integrity sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA== -split2@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" - integrity sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw== +spdx-satisfies@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/spdx-satisfies/-/spdx-satisfies-5.0.1.tgz#9feeb2524686c08e5f7933c16248d4fdf07ed6a6" + integrity sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw== dependencies: - through2 "^2.0.2" + spdx-compare "^1.0.0" + spdx-expression-parse "^3.0.0" + spdx-ranges "^2.0.0" -split@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== - dependencies: - through "2" +sprintf-js@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== - dependencies: - figgy-pudding "^3.5.1" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - -stack-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" - integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== - -standard-version@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/standard-version/-/standard-version-7.0.1.tgz#33e950cf5c571ae0358a7ffae2292aa4547dc504" - integrity sha512-3GR9dPlNpC/osTwb9YsU2KQelGvSORMPUFN7zOUE3HN4yjCTsT57IJAFsyPXPP512QDMSxwwjhxa8Em5vF5F5Q== - dependencies: - chalk "2.4.2" - conventional-changelog "3.1.12" - conventional-changelog-config-spec "2.1.0" - conventional-recommended-bump "6.0.2" - detect-indent "6.0.0" - detect-newline "3.0.0" - dotgitignore "2.1.0" - figures "3.0.0" - find-up "4.1.0" - fs-access "1.0.1" - git-semver-tags "3.0.0" - semver "6.3.0" - stringify-package "1.0.1" - yargs "14.2.0" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" + escape-string-regexp "^2.0.0" -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== +standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= +stat-mode@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-1.0.0.tgz#68b55cb61ea639ff57136f36b216a291800d1465" + integrity sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg== -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= - dependencies: - astral-regex "^1.0.0" - strip-ansi "^4.0.0" +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" +string-argv@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" + integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" + char-regex "^1.0.2" + strip-ansi "^6.0.0" -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== +string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" -string_decoder@^1.0.0, string_decoder@^1.1.1: +string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -7810,87 +6638,61 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-package@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85" - integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg== - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: - ansi-regex "^4.1.0" + ansi-regex "^5.0.1" -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= +strip-ansi@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== dependencies: - is-utf8 "^0.2.0" + ansi-regex "^6.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= - dependencies: - get-stdin "^4.0.1" +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-json-comments@2.0.1: +strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== -style-loader@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.1.2.tgz#1b519c19faf548df6182b93e72ea1a4156022c2f" - integrity sha512-0Mpq1ZHFDCNq1F+6avNBgv+7q8V+mWRuzehxyJT+aKgzyN/yfKTwjYqaYwBgx+11UpQxL21zNQfzzlz+JcGURw== - dependencies: - loader-utils "^1.2.3" - schema-utils "^2.0.1" +style-loader@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.2.tgz#eaebca714d9e462c19aa1e3599057bc363924899" + integrity sha512-RHs/vcrKdQK8wZliteNK4NKzxvLBzpuHMqYmUVWeKa6MkaIQ97ZTOS0b+zapZhy6GcrgWnvWYCMHRirC3FsUmw== -supports-color@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" - integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== - dependencies: - has-flag "^3.0.0" +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== -supports-color@6.1.0, supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== +sumchecker@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42" + integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg== dependencies: - has-flag "^3.0.0" + debug "^4.1.0" supports-color@^5.3.0: version "5.5.0" @@ -7899,136 +6701,132 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -symbol-observable@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" -symbol-tree@^3.2.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +supports-color@^8.0.0, supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" -tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - -terser-webpack-plugin@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" - integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== - dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^2.1.2" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -terser@^4.1.2: - version "4.6.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.1.tgz#913e35e0d38a75285a7913ba01d753c4089ebdbd" - integrity sha512-w0f2OWFD7ka3zwetgVAhNMeyzEbj39ht2Tb0qKflw9PmW9Qbo5tjTh01QJLkhO9t9RDDQYvk+WXqpECI2C6i2A== - dependencies: +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +temp-file@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/temp-file/-/temp-file-3.4.0.tgz#766ea28911c683996c248ef1a20eea04d51652c7" + integrity sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg== + dependencies: + async-exit-hook "^2.0.1" + fs-extra "^10.0.0" + +terser-webpack-plugin@^5.3.7: + version "5.3.8" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.8.tgz#415e03d2508f7de63d59eca85c5d102838f06610" + integrity sha512-WiHL3ElchZMsK27P8uIUh4604IgJyAW47LVXGbEoB21DbQcZ+OuMpGjVYnEUaqcWM6dO8uS2qUbA7LSCWqvsbg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.17" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.16.8" + +terser@^5.10.0, terser@^5.16.8: + version "5.17.3" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.17.3.tgz#7f908f16b3cdf3f6c0f8338e6c1c674837f90d25" + integrity sha512-AudpAZKmZHkG9jueayypz4duuCFJMMNGRMwaPvQKWfxKedh8Z2x3OCoDqIIi1xx5+iwx1u6Au8XQcc9Lke65Yg== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" + source-map-support "~0.5.20" -test-exclude@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" - integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: - glob "^7.1.3" + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" - -text-extensions@^1.0.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" - integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== -text-hex@1.0.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" - integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== +then-fs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/then-fs/-/then-fs-2.0.0.tgz#72f792dd9d31705a91ae19ebfcf8b3f968c81da2" + integrity sha512-5ffcBcU+vFUCYDNi/o507IqjqrTkuGsLVZ1Fp50hwgZRY7ufVFa9jFfTy5uZ2QnSKacKigWKeaXkOqLa4DsjLw== + dependencies: + promise ">=3.2 <8" -throat@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" -through2@^2.0.0, through2@^2.0.2: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" + any-promise "^1.0.0" -through2@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" - integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== +threadedclass@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/threadedclass/-/threadedclass-1.2.1.tgz#1ce1316f6835cec238edabba75421e654f2c5572" + integrity sha512-b8dUXW0K3dUWYrQakKhXvY/Owrnd3p+NKTI0BVEuAU/o7PsLupoNDCadK6V3WwyVLKCy0CS/d1xBmc6uZNPgOw== dependencies: - readable-stream "2 || 3" + callsites "^3.1.0" + eventemitter3 "^4.0.4" + is-running "^2.1.0" + tslib "^1.13.0" -through@2, "through@>=2.2.7 <3": +through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timed-out@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== +tmp-promise@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" + integrity sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ== dependencies: - setimmediate "^1.0.4" - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + tmp "^0.2.0" -to-array@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" - integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= +tmp@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== to-regex-range@^5.0.1: version "5.0.1" @@ -8037,142 +6835,105 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - toidentifier@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== -toposort@^1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" - integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= - -tough-cookie@^2.3.3, tough-cookie@^2.3.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - -tr46@^1.0.1: +toidentifier@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= - dependencies: - punycode "^2.1.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -trim-newlines@^1.0.0: +token-stream@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= - -trim-newlines@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" - integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4" + integrity sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg== -trim-off-newlines@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" - integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -triple-beam@^1.2.0, triple-beam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" - integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== +truncate-utf8-bytes@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" + integrity sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ== + dependencies: + utf8-byte-length "^1.0.1" -ts-jest@^24.2.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" - integrity sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ== +ts-jest@^29.1.0: + version "29.1.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.0.tgz#4a9db4104a49b76d2b368ea775b6c9535c603891" + integrity sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA== dependencies: bs-logger "0.x" - buffer-from "1.x" fast-json-stable-stringify "2.x" - json5 "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" lodash.memoize "4.x" make-error "1.x" - mkdirp "0.x" - resolve "1.x" - semver "^5.5" - yargs-parser "10.x" + semver "7.x" + yargs-parser "^21.0.1" -ts-loader@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.2.1.tgz#67939d5772e8a8c6bdaf6277ca023a4812da02ef" - integrity sha512-Dd9FekWuABGgjE1g0TlQJ+4dFUfYGbYcs52/HQObE0ZmUNjQlmLAS7xXsSzy23AMaMwipsx5sNHvoEpT2CZq1g== +ts-loader@^9.4.2: + version "9.4.2" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.2.tgz#80a45eee92dd5170b900b3d00abcfa14949aeb78" + integrity sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA== dependencies: - chalk "^2.3.0" - enhanced-resolve "^4.0.0" - loader-utils "^1.0.2" + chalk "^4.1.0" + enhanced-resolve "^5.0.0" micromatch "^4.0.0" - semver "^6.0.0" - -ts-node@^8.6.2: - version "8.6.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.6.2.tgz#7419a01391a818fbafa6f826a33c1a13e9464e35" - integrity sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg== - dependencies: - arg "^4.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.6" - yn "3.1.1" + semver "^7.3.4" -tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== +tslib@^1.13.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= +tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" +tsscmp@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" + integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +tunnel@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" + integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= +twos-complement-buffer@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/twos-complement-buffer/-/twos-complement-buffer-0.0.1.tgz#e461a248d5c14a6d90afd031b2677f31da127d29" + integrity sha512-Ev3p2GfB2GO8pcyb7jIvctS9RAjSZrF/K+u5s3KN00ajY11Dda2oMqI72nXaHVU7doGYNXc0mJG6exWAbmzZiA== dependencies: - prelude-ls "~1.1.2" + uint-buffer "^0.1.0" -type-detect@^4.0.0, type-detect@^4.0.5: +type-detect@4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-is@~1.6.17, type-is@~1.6.18: +type-fest@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" + integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -8180,670 +6941,530 @@ type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript@^3.7.5: - version "3.7.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" - integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== +typedi@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/typedi/-/typedi-0.8.0.tgz#d8e203bd1d41a96e2b0a5c6295147d74b2b2d03e" + integrity sha512-/c7Bxnm6eh5kXx2I+mTuO+2OvoWni5+rXA3PhXwVWCtJRYmz3hMok5s1AKLzoDvNAZqj/Q/acGstN0ri5aQoOA== -uglify-js@3.4.x: - version "3.4.10" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" - integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== - dependencies: - commander "~2.19.0" - source-map "~0.6.1" +typescript@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== uglify-js@^3.1.4: - version "3.7.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.4.tgz#e6d83a1aa32ff448bd1679359ab13d8db0fe0743" - integrity sha512-tinYWE8X1QfCHxS1lBS8yiDekyhSXOO6R66yNOCdUJeojxxw+PX2BHAz/BWyW7PQ7pkiWVxJfIEbiDxyLWvUGg== - dependencies: - commander "~2.20.3" - source-map "~0.6.1" - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== +uid-safe@2.1.5, uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" + integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA== dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" + random-bytes "~1.0.0" -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== - -unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" - integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== +uint-buffer@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/uint-buffer/-/uint-buffer-0.1.0.tgz#35f2f59fa253d338affcdb6f377750642bd1cf59" + integrity sha512-7xjpjCTijFIXAMxN7OMRfykpCMVfbCrlAmAt2RIlihvkHgvkNV5DBFzyc8OpIQeVpRXJkgXBwmKos4hD8DrX1g== -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + crypto-random-string "^2.0.0" -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= +update-browserslist-db@^1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + escalade "^3.1.1" + picocolors "^1.0.0" -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= +update-notifier@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" + integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== + dependencies: + boxen "^5.0.0" + chalk "^4.1.0" + configstore "^5.0.1" + has-yarn "^2.1.0" + import-lazy "^2.1.0" + is-ci "^2.0.0" + is-installed-globally "^0.4.0" + is-npm "^5.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.1.0" + pupa "^2.1.1" + semver "^7.3.4" + semver-diff "^3.1.1" + xdg-basedir "^4.0.0" + +upload-files-express@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/upload-files-express/-/upload-files-express-0.4.0.tgz#9aefa8323b3d51a8fb306b9d3895985ec0a39688" + integrity sha512-ET3Pcstq4F1gNCPtfy9cK8WAYhg81NoiC1qjYaptGT2ODkT8FMarNbGh5Ku71/B6Ig39o58JibfEkObmhJFY0Q== + dependencies: + formidable "^2.0.1" uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - url-parse-lax@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== dependencies: prepend-http "^2.0.0" -url-to-options@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" - integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= +use-isomorphic-layout-effect@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" + integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" +use-sync-external-store@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +utf8-buffer@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/utf8-buffer/-/utf8-buffer-0.2.0.tgz#a4530a606d9d2b0348456a393eaf836b62fed2f3" + integrity sha512-DygDeOmOPQRjxnnv8LdfjoSQgG9EgJFH1m/1QcrKkDOxzoOcLLqZ2ONzRYHmiRqJYQYnAvV+zv2Wgk5tXjr4aA== + +utf8-byte-length@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" + integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA== -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util-extend@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" - integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= - -util.promisify@1.0.0, util.promisify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== - dependencies: - inherits "2.0.3" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -utila@^0.4.0, utila@~0.4: +utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" - integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== - -v8-compile-cache@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" - integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== +v8-to-istanbul@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" + builtins "^1.0.3" -vary@~1.1.2: +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= +verror@^1.10.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.1.tgz#4bf09eeccf4563b109ed4b3d458380c972b0cdeb" + integrity sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg== dependencies: assert-plus "^1.0.0" core-util-is "1.0.2" extsprintf "^1.2.0" -vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== - -w3c-hr-time@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" - integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= +vmix-js-utils@^4.0.16: + version "4.0.16" + resolved "https://registry.yarnpkg.com/vmix-js-utils/-/vmix-js-utils-4.0.16.tgz#084926767cbafc9334dafbe4fee34017b1b81822" + integrity sha512-fiJTSatAzaIZMVlWsGDhY4LfrGPohpGy4w5/X6BCEy3yFIqn2RJEkAXiFe9lqHaqWIERMSXg37slw07dTAuQMw== dependencies: - browser-process-hrtime "^0.1.2" + "@xmldom/xmldom" "^0.8.2" + lodash "^4.17.21" + querystring "^0.2.1" + xpath "^0.0.32" -walker@^1.0.7, walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= - dependencies: - makeerror "1.0.x" +void-elements@3.1.0, void-elements@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== -watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== +walk@2.3.15: + version "2.3.15" + resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.15.tgz#1b4611e959d656426bc521e2da5db3acecae2424" + integrity sha512-4eRTBZljBfIISK1Vnt69Gvr2w/wc3U6Vtrw7qiN5iqYJPH7LElcYh/iU4XWhdCy2dZqv1ToMyYlybDylfG/5Vg== dependencies: - chokidar "^2.0.2" - graceful-fs "^4.1.2" - neo-async "^2.5.0" + foreachasync "^3.0.0" -web-midi-api@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/web-midi-api/-/web-midi-api-2.0.6.tgz#fd5647cb4b9647429d1794a6c8bfef3f216d4a97" - integrity sha512-ngsQ734SUDlnKlD9g6cDPhX9ZO8nrA0jl7qZ/z1asUBusZBRGatevxjoF8cPPANG61cvy6Iq/c6iL0CCi32vlw== +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: - jzz "^0.8.7" - -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + makeerror "1.0.12" -webmidi@^2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/webmidi/-/webmidi-2.5.1.tgz#e98b0bb5356afb5112aaff7eaac23606cf0b71d0" - integrity sha512-rX9/vBBSnSZR04ZZcLWCe/ujOizH9f/Q9HX11+Zw+HHwOy7edUTbbC3Axc2RjoiDQ2W7RkK1tY4yv0nYSfUcJg== - -webpack-cli@^3.3.10: - version "3.3.10" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.10.tgz#17b279267e9b4fb549023fae170da8e6e766da13" - integrity sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg== - dependencies: - chalk "2.4.2" - cross-spawn "6.0.5" - enhanced-resolve "4.1.0" - findup-sync "3.0.0" - global-modules "2.0.0" - import-local "2.0.0" - interpret "1.2.0" - loader-utils "1.2.3" - supports-color "6.1.0" - v8-compile-cache "2.0.3" - yargs "13.2.4" - -webpack-sources@^1.4.0, webpack-sources@^1.4.1: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack@^4.41.0: - version "4.41.5" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.5.tgz#3210f1886bce5310e62bb97204d18c263341b77c" - integrity sha512-wp0Co4vpyumnp3KlkmpM5LWuzvZYayDwM2n17EHFr4qxBBbRokC7DJawPJC7TfSFZ9HZ6GsdH40EBj4UV0nmpw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.1.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.1" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.3" - watchpack "^1.6.0" - webpack-sources "^1.4.1" - -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== dependencies: - iconv-lite "0.4.24" - -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" -whatwg-url@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" - integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== +wavefile@^8.4.4: + version "8.4.6" + resolved "https://registry.yarnpkg.com/wavefile/-/wavefile-8.4.6.tgz#8c99809df1a344edb12839da69e588bf53c7e483" + integrity sha512-mKvPtkXTFE3U8Uo8qJr/hCJP3booCI09vsoWY3OHrdKB+8ZefO/5/wSRZSbPSgFDB+WWn3Am3c01h/sguTYuyA== dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" + alawmulaw "^5.0.2" + base64-arraybuffer-es6 "^0.3.1" + bitdepth "^7.0.2" + byte-data "^16.0.3" + imaadpcm "^4.1.2" -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== +web-midi-api@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/web-midi-api/-/web-midi-api-2.2.5.tgz#bdb230c5facf76ebeff4c2ad7e74bc528eed6ad6" + integrity sha512-ogBnSn0WvGyfiHzwIfkCR47/uwHNXpCdKzHmfsce0zOqlxH/zdPBT5PGEZcsBgbnJrFomqKZQ2dONHBehVx/KQ== dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" + jzz "^1.6.2" -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= +webmidi@^2.5.1: + version "2.5.3" + resolved "https://registry.yarnpkg.com/webmidi/-/webmidi-2.5.3.tgz#e20fda6fbd39edd6145d4499174b65e514fde352" + integrity sha512-PyMGvKcDGpvbQUfnmBORQJciyG3VAZ4aHlGy1iRZ3uEs4kG4HCvI7KRthUpM1vuHDPL98lidRIUaoRomkJtWtg== -which@1.3.1, which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== +webpack-cli@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.1.tgz#c211ac6d911e77c512978f7132f0d735d4a97ace" + integrity sha512-OLJwVMoXnXYH2ncNGU8gxVpUtm3ybvdioiTvHgUyBuyMLKiVvWy+QObzBsMtp5pH7qQoEuWgeEUQ/sU3ZJFzAw== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^2.1.0" + "@webpack-cli/info" "^2.0.1" + "@webpack-cli/serve" "^2.0.4" + colorette "^2.0.14" + commander "^10.0.1" + cross-spawn "^7.0.3" + envinfo "^7.7.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^3.1.1" + rechoir "^0.8.0" + webpack-merge "^5.7.3" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.82.1: + version "5.82.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.82.1.tgz#8f38c78e53467556e8a89054ebd3ef6e9f67dbab" + integrity sha512-C6uiGQJ+Gt4RyHXXYt+v9f+SN1v83x68URwgxNQ98cvH8kxiuywWGP4XeNZ1paOzZ63aY3cTciCEQJNFUljlLw== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.14.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.9" + 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.1.2" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.7" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== +wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: - string-width "^1.0.2 || 2" + string-width "^1.0.2 || 2 || 3 || 4" -window-size@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" - integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY= +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + +wildcard@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== winston-color@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/winston-color/-/winston-color-1.0.0.tgz#7dcf28fded016585247f2aadc10ce8aafbe1fac6" - integrity sha1-fc8o/e0BZYUkfyqtwQzoqvvh+sY= + integrity sha512-I6bB13vkglrYfOna1YoSFt6eHeafP6r2w+G192vyfgtKBnxoxXCV+TbiY3IJTT+kW3Stqsb6TJzT+ZGHXsRxDw== dependencies: winston "^2.1.1" -winston-elasticsearch@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/winston-elasticsearch/-/winston-elasticsearch-0.8.3.tgz#7cfebc24238729fb09bb6de0cbc931b3923fe16e" - integrity sha512-+N1o5CCCZLT6YlmovHxOW8hh1d9RAFXKfwdkPDzqgcZ/XgdV5bSBuYDuIW16+lrTLPRLxOmM78lGz4ZDJwQ5wQ== - dependencies: - "@elastic/elasticsearch" "^7.5.0" - dayjs "^1.8.18" - debug "4.1.1" - lodash.defaults "^4.2.0" - lodash.omit "^4.5.0" - promise "^8.0.3" - retry "^0.12.0" - winston "^3.2.1" - winston-transport "4.3.0" - -winston-transport@4.3.0, winston-transport@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.3.0.tgz#df68c0c202482c448d9b47313c07304c2d7c2c66" - integrity sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A== - dependencies: - readable-stream "^2.3.6" - triple-beam "^1.2.0" - winston@^2.1.1: - version "2.4.4" - resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.4.tgz#a01e4d1d0a103cf4eada6fc1f886b3110d71c34b" - integrity sha512-NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q== + version "2.4.7" + resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.7.tgz#5791fe08ea7e90db090f1cb31ef98f32531062f1" + integrity sha512-vLB4BqzCKDnnZH9PHGoS2ycawueX4HLqENXQitvFHczhgW2vFpSOn31LZtVr1KU8YTw7DS4tM+cqyovxo8taVg== dependencies: - async "~1.0.0" + async "^2.6.4" colors "1.0.x" cycle "1.0.x" eyes "0.1.x" isstream "0.1.x" stack-trace "0.0.x" -winston@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.2.1.tgz#63061377976c73584028be2490a1846055f77f07" - integrity sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw== - dependencies: - async "^2.6.1" - diagnostics "^1.1.1" - is-stream "^1.1.0" - logform "^2.1.1" - one-time "0.0.4" - readable-stream "^3.1.1" - stack-trace "0.0.x" - triple-beam "^1.3.0" - winston-transport "^4.3.0" - -wolfy87-eventemitter@5.2.6: - version "5.2.6" - resolved "https://registry.yarnpkg.com/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.6.tgz#cc5de965d34099e5c14ec189ee72553802d3ace2" - integrity sha512-n+bSucT1j9ZEoosxnfuH81bWqtZG4QEtZ9WEuiXz9YQAHEktGYKoSoMTKWTJEcYux8lWoqp1KqHPBpwvJKFFTw== +with@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" + integrity sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w== + dependencies: + "@babel/parser" "^7.9.6" + "@babel/types" "^7.9.6" + assert-never "^1.2.1" + babel-walk "3.0.0-canary-5" -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wolfy87-eventemitter@5.2.9: + version "5.2.9" + resolved "https://registry.yarnpkg.com/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz#e879f770b30fbb6512a8afbb330c388591099c2a" + integrity sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw== -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: - errno "~0.1.7" + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -write-file-atomic@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" - integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: - graceful-fs "^4.1.11" imurmurhash "^0.1.4" + is-typedarray "^1.0.0" signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" -ws@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.0.0.tgz#79351cbc3f784b3c20d0821baf4b4ff809ffbf51" - integrity sha512-cknCal4k0EAOrh1SHHPPWWh4qm93g1IuGGGwBjWkXmCG7LsDtL8w9w+YVfaF+KSVwiHQKDIMsSLBVftKf9d1pg== - dependencies: - async-limiter "^1.0.0" - -ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== dependencies: - async-limiter "~1.0.0" + imurmurhash "^0.1.4" + signal-exit "^3.0.7" -ws@^7.1.2: - version "7.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.1.tgz#03ed52423cd744084b2cf42ed197c8b65a936b8e" - integrity sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A== +ws@8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== -ws@~6.1.0: - version "6.1.4" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" - integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== - dependencies: - async-limiter "~1.0.0" +ws@~8.11.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== -xml2js@^0.4.19: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== +xml2js@^0.4.19, xml2js@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.5.0.tgz#d9440631fbb2ed800203fad106f2724f62c493b7" + integrity sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA== dependencies: sax ">=0.6.0" xmlbuilder "~11.0.0" +xmlbuilder@>=11.0.1, xmlbuilder@^15.1.1: + version "15.1.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" + integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== + xmlbuilder@^9.0.7: version "9.0.7" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + integrity sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ== xmlbuilder@~11.0.0: version "11.0.1" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== -xmlhttprequest-ssl@~1.5.4: - version "1.5.5" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" - integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= +xmlhttprequest-ssl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz#91360c86b914e67f44dce769180027c0da618c67" + integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A== -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +xpath@^0.0.32: + version "0.0.32" + resolved "https://registry.yarnpkg.com/xpath/-/xpath-0.0.32.tgz#1b73d3351af736e17ec078d6da4b8175405c48af" + integrity sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw== -y18n@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yaml@^1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.7.2.tgz#f26aabf738590ab61efaca502358e48dc9f348b2" - integrity sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw== - dependencies: - "@babel/runtime" "^7.6.3" - -yargs-parser@10.x, yargs-parser@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" - -yargs-parser@13.1.1, yargs-parser@^13.1.0, yargs-parser@^13.1.1: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.0.tgz#cdd7a97490ec836195f59f3f4dbe5ea9e8f75f08" - integrity sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-unparser@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" - integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== - dependencies: - flat "^4.1.0" - lodash "^4.17.15" - yargs "^13.3.0" +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs@13.2.4: - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - os-locale "^3.1.0" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.0" - -yargs@13.3.0, yargs@^13.3.0: - version "13.3.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" - integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.1" - -yargs@14.2.0: - version "14.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.0.tgz#f116a9242c4ed8668790b40759b4906c276e76c3" - integrity sha512-/is78VKbKs70bVZH7w4YaZea6xcJWOAwkhbR0CFuZBmYtfTYF0xjGJF43AYd8g2Uii1yJwmS5GR2vBmrc32sbg== - dependencies: - cliui "^5.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" +yaml@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.2.tgz#ec551ef37326e6d42872dad1970300f8eb83a073" + integrity sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA== + +yargs-parser@^21.0.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.0.1, yargs@^17.3.1, yargs@^17.5.1, yargs@^17.7.1: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^15.0.0" - -yargs@^3.32.0: - version "3.32.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" - integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU= - dependencies: - camelcase "^2.0.1" - cliui "^3.0.3" - decamelize "^1.1.1" - os-locale "^1.4.0" - string-width "^1.0.1" - window-size "^0.1.4" - y18n "^3.2.0" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" yargs@~1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.2.6.tgz#9c7b4a82fd5d595b2bf17ab6dcc43135432fe34b" - integrity sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s= + integrity sha512-wwBCGnWIeR7M6d7Wmd4NT48TI8jEzRXFzmYGTNpsHZZ9Uu13vj+p6EawS7kGrzBvkX6rF7vYjUrQnwEOI7QOIw== dependencies: minimist "^0.1.0" -yeast@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" - integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==