diff --git a/.github/workflows/update-advanced-settings-toc.yml b/.github/workflows/update-advanced-settings-toc.yml index 1266830..5e58316 100644 --- a/.github/workflows/update-advanced-settings-toc.yml +++ b/.github/workflows/update-advanced-settings-toc.yml @@ -2,7 +2,7 @@ name: Update Advanced Settings Markdown TOC on: workflow_dispatch: schedule: - - cron: '0 3 * * *' + - cron: '0 0 29 2 1' jobs: update-toc: diff --git a/README.md b/README.md index 22d67bb..6348c64 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Directions on how to deploy a TURN server are listed in the turnserver.md file. ## Server side / API software Since OBS.Ninja uses peer-2-peer technology, video connections are made directly between viewer and publisher in 90% of cases. Hosting a TURN server yourself may help improve performance, but less than 1% of users will see any benefit of this. Details on how to deploy a TURN server are provided. For those capable of hosting their own TURN server, that would be appreciated if possible, as TURN servers are the only real cost incurred by OBS.Ninja at present. (other than time, of course) -Other than TURN servers, OBS.Ninja also uses public STUN servers and a hosted handshake server. These are used to facilitate the initial setup of peer connections and are generally not required after a peer connection is established. These servers are free to access and use, even for private deployments. The handshake server's code is currently not available, so basic access to the Internet is still required to use OBS.Ninja even with a private deployment. +Other than TURN servers, OBS.Ninja also uses public STUN servers and a hosted handshake server. These are used to facilitate the initial setup of peer connections and are generally not required after a peer connection is established. These servers are free to access and use, even for private deployments. As of Version 17.3 of OBS.Ninja, you can host your own handshake server or use a third-party managed one (such as piesocket.com); please see details here: https://github.com/steveseguin/websocket_server Development builds of OBS.Ninja may include debugging software, but in-production releases have this removed. Double check to ensure "console.re" debugging is disabled before deployment, just to be safe. @@ -63,9 +63,6 @@ http://chat.overlay.ninja/ A website designed to also work with OBS.Ninja as a Broadcasting tool. Share your webcam, window, desktop, or video file with friends and family. Peer-2-peer, so privacy can be maintained, but you can also list your broadcasts for others to watch. https://steves.app/ -### StageTEN.tv -A browser-based studio solution and simplified alternative to OBS, with built-in OBS.Ninja functionality. It is a server-based approach to group interactions and live production. Steve Seguin is affiliated with StageTEn, yet StageTEN is not affiliated with OBS.Ninja. - ## Privacy I try to avoid data collection whenever possible and video streams are generally designed to be private, but use at your own risk. It is best to not share links created with OBS.Ninja with those you do not trust. I've provided instructions on how to deploy a TURN server if IP-address privacy is an issue for you. See: [turnserver.md](turnserver.md) diff --git a/electron.html b/electron.html index 31797e0..622f7ac 100644 --- a/electron.html +++ b/electron.html @@ -1,562 +1,562 @@ - - - - - - - - - - -
- - - - -

-
-
- - - -
-
- -
-
- - -
- -
-
- - - - + + + + + + + + + + +
+ + + + +

+
+
+ + + +
+
+ +
+
+ + +
+ +
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html index e56be31..541addc 100644 --- a/index.html +++ b/index.html @@ -605,8 +605,8 @@
See the documentation for more options and info.

- Try out the advanced invite generator here also. - + Try out the advanced invite generator here also. +
@@ -782,7 +782,6 @@
  • https://invite.cam is a free service provided that can help obfuscuate the URL parameters of an invite link given to guests.
  • Adding &showonly=SOME_OBS_VIRTUALCAM to the guest invite links allows for only a single video to be seen by the guests; this can be output of the OBS Virtual Camera for example

  • - For advanced URL options and parameters, see the Wiki. diff --git a/main.css b/main.css index 8536750..5438484 100644 --- a/main.css +++ b/main.css @@ -1,2904 +1,2904 @@ -:root { - --background-color: #141926; - --container-color: #373737; - --button-color: #2A2A2A; - --blue-accent: #4a4c63; - --red-accent: #553737; - --green-accent: #3f4f50; - --olive-accent: #535D32; - --regular-margin: 10px; - --director-margin: 15px 20px 0 0; - --fit-style: contain; - --fadein-speed: 0; - --video-margin: 0px; -} - -* { - padding: 0; - margin: 0; - box-sizing: border-box; - border: 0; -} - - -table { - display: inline-block; - padding:10px; - margin:10px; -} - -#bigPlayButton { - margin:0 auto; - background-color: #0000; - color: #; - font-family: Cousine, monospace; - font-size: 4em; - line-height: 1.5em; - letter-spacing: 0.0em; - text-shadow: 0.05em 0.05em 0px rgba(0,0,0,1); - width:100%; - height:100vh; - z-index: 1; - vertical-align: top; - text-align: center; - top: 0; - position: fixed; - overflow-wrap: anywhere; - padding:3%; - pointer-events: none -} - -#playButton { - font-size: 50vh; - border-radius: 50vh; - font-size: min(50vw, 50vh); - cursor:pointer; - opacity:100%; - margin-top: 20vh; - background-color:#444; -} - -tr { - padding:4px; -} -th { - padding:4px; -} - -.meter { - display: inline-block; - width: 0px; - height: 10px; - background: green; - transition: all 100ms linear; -} -.meter2 { - display: inline-block; - width: 0px; - height: 10px; - background: yellow; - transition: all 50ms linear; -} - -#mynetwork { - width: 600px; - height: 400px; - border: 1px solid lightgray; -} - -.email { - unicode-bidi: bidi-override; - direction: rtl; - user-select: none; -} - -a:link { - text-decoration: none; - color: #B9DFF9; -} - -/* visited link */ - -a:visited { - text-decoration: none; - color: #99BFD9; -} - - -/* mouse over link */ - -a:hover { - color: #048AE8; -} - - -/* selected link */ - -a:active { - color: #D9E4EB; -} - -input { - border-radius: 4px; - padding: 2px; - -webkit-app-region: no-drag; -} - -button.grey { - -webkit-app-region: no-drag; - padding: 10px; - margin: 10px 0px; - cursor: pointer; - border-radius: 2px; - background-color: var(--button-color); - color: white; -} - - -#miniPerformer>#videosource{ - width: 80px; - height: 45px; - margin: 5px; - background-color: #464749 !important; - background-size: 50%; -} - -#miniPerformer>#previewWebcam{ - width: 80px; - height: 45px; - margin: 5px; - background-color: #464749 !important; - background-size: 50%; -} - -#reportbutton{ - visibility: hidden; -} - -.red { - background-color: #840000 !important; -} - -button.red { - -webkit-app-region: no-drag; - padding: 10px; - margin: 10px 0px; - cursor: pointer; - border-radius: 2px; - color: white; -} - -button { - -webkit-app-region: no-drag; - padding: 7px 10px 6px 10px; - user-select: none; - margin: 10px 0px; - cursor: pointer; - border-radius: 2px; -} - - -button.white { - -webkit-app-region: no-drag; - padding: 6px 10px 4px 9px; - ; - margin: 10px 0px; - cursor: pointer; - border-radius: 2px; - background-color: white; - color: black; - border: 1px solid black; -} - -button.white:active { - -webkit-app-region: no-drag; - padding: 6px 10px 4px 9px; - ; - margin: 10px 0px; - cursor: pointer; - border-radius: 2px; - background-color: black; - color: white; - border: 1px solid black; -} - -#header { - width: 100%; - padding: 1px; - background-color: #0F131D; - color: #FFF; -} -#head5 { - display: inline-block; - text-decoration: none; - color: white; - text-align: right; - margin-right: 10px; - pointer-events: none; - float: right; -} - -#overlayMsgs{ - margin:0 auto; - background-color: #0000; - color: white; - font-family: Cousine, monospace; - font-size: 6vh; - line-height: 8vh; - letter-spacing: 0.0em; - text-shadow: 0.05em 0.05em 0px rgba(0,0,0,1); - width:100%; - height:100vh; - z-index: 7; - vertical-align: top; - text-align: center; - top: 0; - position: fixed; - overflow-wrap: anywhere; - padding:2% 3%; - pointer-events: none -} -#overlayMsgs span{ - background-color: #000B; - padding: 2px; - margin: 0.5vh; - text-align: center; - width:100%; - pointer-events: none -} - -.credits { - color: #101020; - position: fixed; - bottom: 0; - right: 0; - z-index: -1; - font-size: 80%; -} - -.credits>a { - color: #101020; -} - -.credits>a:visited { - color: #101020; -} - -.chevron { - padding: 0px 6px; -} - -.chevron::before { - border-style: solid; - border-width: 0.14em 0.14em 0 0; - content: ''; - display: inline-block; - height: 0.32em; - left: 0.15em; - position: relative; - top: .43em; - transform: rotate(-45deg); - vertical-align: top; - width: 0.32em; -} - -.chevron.bottom::before { - top: .28em; - transform: rotate(135deg); -} - -.chevron.right::before { - top: .28em; - transform: rotate(45deg); -} - -.label { - float: left; - font-size: 1.2em; - color: white; - display: inline-block; - position: absolute; - bottom: 0; - align-self: center; - z-index: 1000; - margin: 5% 20%; - padding: 1%; - background-color: black; -} - -.pressed { - background: #1e0000; - -webkit-box-shadow: inset 0px 0px 1px #b90000; - -moz-box-shadow: inset 0px 0px 1px #b90000; - box-shadow: inset 0px 0px 1px #b90000; - outline: none; - color: white; -} - -.row { - align-content: center; - text-align: center; - margin-top: 10px; -} - -hr { - height: 2px; - border-width: 0; - color: gray; - background-color: gray; -} - -.orderspan{ - font-size: 50%; - display: inline-block; - margin: auto; - text-align: center; - width: 49px; - height: 22px; - top: 5px; - position: relative; - user-select: none; -} -/* Clear floats after the columns */ - -.row:after { - content: ""; - display: table; - clear: both; -} - -.vidcon { - max-width: 100%; - border: 0; -} - -.vidcon:nth-of-type(3n) { - grid-column: 2; -} - -.vidcon:nth-of-type(3n) { - grid-row: span; -} - -.tile { - object-fit: var(--fit-style); - background-color: black; - width: 100%; - height: 100%; - border: 0; - padding: 0; - overflow: hidden; - margin: var(--video-margin); -} - -#gridlayout { - padding: 0; - width: 100%; - height: 100%; - grid-gap: 0; - overflow: hidden; - justify-items: stretch; - grid-auto-flow: dense; - grid-auto-columns: minmax(50%, auto); - grid-auto-rows: minmax(50%, auto); - border: 0; - margin: 0; -} - - -/* Invite link generator */ - -.invite_setting_group { - margin: 20px 0px; - background-color: #d2d2d2; - padding: 10px; -} - -.invite_setting_group h4 { - margin: 10px 0px 20px; -} - -.invite_setting_item { - margin: 10px 0px; -} - -.directorsgrid { - justify-items: normal; - grid-auto-columns: minmax(100px, 530px); - grid-auto-rows: minmax(100px, 300px); - display: block ! important; - overflow-y: auto !important; -} - -.directorsgrid .vidcon video { - margin: 0 5px; - padding:0; - width: 100%; - height: 148px; - max-width: 260px; -} - -.directorsgrid .vidcon { - display: inline-block !important; - width: 269.7px !important; - background: #7E7E7E; - color: #FCFCFC; - vertical-align: top; -} - -.directorsgrid .vidcon>.las { - color: black; - background: #999999; - width: 90%; -} - -.puslate { - border-radius: 50%; - box-shadow: 0 0 0 0 rgba(14, 19, 26, 1); - transform: scale(1); - animation: pulse 2s infinite; -} - -.mirror { - transform: scaleX(-1); -} - -.notification { - position: relative; - top: -40px; - right: -33px; - padding: 2px 0; - border-radius: 50%; - background: red; - color: white; - width: 11px; - height: 11px; - margin: 0; -} -.queueNotification { - position: relative; - top: -40px; - right: -33px; - padding: 2px 0; - border-radius: 50%; - background: #335c3a; - color: white; - width: 23px; - height: 23px; - margin: 0; -} - - -button.glyphicon-button:focus, -button.glyphicon-button:active:focus, -button.glyphicon-button.active:focus, -button.glyphicon-button.focus, -button.glyphicon-button:active.focus, -button.glyphicon-button.active.focus { - outline: none !important; -} - -#main { - -webkit-tap-highlight-color: rgba(255, 255, 255, 0) !important; - -webkit-tap-highlight-color: transparent !important; - outline: 0px !important; - height:100%; -} - -#controlButtons { - position: fixed; - z-index: 5; - bottom: 0px; - width: 100%; - display: none; - justify-content: center; - align-items: center; - height: 60px; - border: 0; - pointer-events: none; -} - -#subControlButtons { - display: flex; - border-radius: 38px; - background-color: #030303dd; - padding: 5px 7px; - position: absolute; - pointer-events: auto; -} -#container.vidcon { - height:100%; -} - -@media only screen and (max-width: 640px){ - #subControlButtons { - transform: scale(0.9) translateY(10%); - } -} -@media only screen and (max-width: 400px){ - #subControlButtons { - transform: scale(0.8) translateY(20%); - } -} -@media only screen and (max-width: 300px){ - #subControlButtons { - padding: 0px; - } -} - -@media only screen and (max-width: 620px){ - #obsState { - top: 10px !important; - transform: scale(0.9); - } -} -@media only screen and (max-width: 400px){ - #obsState { - top: 20px !important; - transform: scale(0.8); - } -} -@media only screen and (max-width: 300px){ - #obsState { - top: 30px !important; - transform: scale(0.7); - } -} -obsState - -/* Node selector to prioritise this selector above .float */ -button.btnArmTransferRoom{ - width:auto; - margin-left: 2px; - height:38px; - border-radius: 15px; -} -button.btnArmTransferRoom i{ - margin-right:3px; -} -button.btnArmTransferRoom:hover{ - background-color: var(--green-accent); -} - -button.btnArmTransferRoom.selected{ - background-color: #840000; -} - -@media only screen and (max-height: 540px){ - #subControlButtons { - transform: scale(0.88); - } - #gridlayout>#container.vidcon { - height:88% - } - #controlButtons { - height:54px; - } -} -@media only screen and (max-height: 500px){ - #subControlButtons { - transform: scale(0.87); - } - #gridlayout>#container.vidcon { - height:87% - } - #controlButtons { - height:54px; - } -} -@media only screen and (max-height: 400px){ - #subControlButtons { - transform: scale(0.85); - } - #logoname{ - display:none; - } - #head1{ - display:none; - } - #head4{ - display:none; - } - #head5{ - display:none; - } - #head2{ - display:none; - } - #gridlayout>#container.vidcon { - height:85% - } - #controlButtons { - height:50px; - } -} -@media only screen and (max-height: 300px){ - #gridlayout>#container.vidcon { - height:81% - } - #subControlButtons { - transform: scale(0.81); - } - #controlButtons { - height:46.2px; - } - #head2 { - display:none !important; - } -} -@media only screen and (max-height: 240px){ - #gridlayout>#container.vidcon { - height:78% - } - #subControlButtons { - transform: scale(0.77); - } - #controlButtons { - height:46.2px; - } -} -@media only screen and (max-height: 190px){ - #gridlayout>#container.vidcon { - height:75% - } - #subControlButtons { - transform: scale(0.73); - } - #controlButtons { - height:42px - } -} -@media only screen and (max-height: 160px){ - #gridlayout>#container.vidcon { - height:70% - } - #subControlButtons { - transform: scale(0.65); - } - #controlButtons { - height:38px - } -} -@media only screen and (max-height: 120px){ - #gridlayout>#container.vidcon { - height:70% - } - #subControlButtons { - transform: scale(0.52); - } - #controlButtons { - height:30px - } -} - -#header:empty{ - display:none; -} - -@keyframes pulse { - 0% { - transform: scale(1); - box-shadow: 0 0 0 0 rgba(14, 19, 26, 0.7); - } - 15% { - transform: scale(1.2); - box-shadow: 0 0 0 10px rgba(2, 3, 4, 0); - } - 50% { - transform: scale(1.0); - box-shadow: 0 0 0 0 rgba(14, 19, 26, 0); - } - 85% { - transform: scale(0.95); - box-shadow: 0 0 0 0 rgba(14, 19, 26, 0); - } - 100% { - transform: scale(1); - box-shadow: 0 0 0 0 rgba(14, 19, 26, 0); - } -} - -.la-sliders-h { - cursor:pointer; -} - -.la-sliders-h { - cursor:pointer; -} - -select { - cursor:pointer; -} - -input[type='checkbox'] { cursor:pointer; } -input[type='radio'] { cursor:pointer; } - -.icn-spinner { - animation: spin-animation 3s infinite; - display: inline-block; - z-index: 10; -} - -@keyframes spin-animation { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(359deg); - } -} - -html { - border: 0; - margin: 0; - outline: 0; -} - -li { - margin: 0.1em 0; - padding-left: 0.1em; - line-height: 1.3em; -} - -body { - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; - color: var(--gray90); - font-family: "Lato", sans-serif; - padding: 0 0px; - height: 100%; - width: 100%; - background-color: var(--background-color); - font-family: Helvetica, Arial, sans-serif; - display: flex; - flex-flow: column; - border: 0; - margin: 0; - opacity: 1; - transition: opacity .1s linear; -} - -.hidden { - visibility: hidden; - opacity: 0; -} - -.previewWebcam { - max-width: 640px; - max-width: 83vw; - height: 30vh; - opacity:1; - animation: fading 0.2s; -} - -#getPermissions{ - font-size: 110%; - border: 3px solid #99A; - cursor: pointer; - background-color: #cce0ff; - margin: 20px; - padding: 10px 50px; - text-align:center; -} - -.gowebcam { - font-size: 110%; - border: 3px solid #DDDDDD; - cursor: pointer; - background-color: #DDDDDD; - margin: 20px; - padding: 10px 50px; -} -.gowebcam:enabled { - background-color: #3C3 !important; - color: black; - font-weight: bold !important;; -} - -.mainmenuclass { - display: inherit; -} - -.gobutton { - font-size: 110%; - padding: 10px; - border: 3px solid #DDDDDD; - cursor: pointer; - background-color: #99BFD9; - color: black; - font-weight: bold; -} - -.infoblob { - color: white; - width: 100%; - padding: 20px; - max-width: 1280px; -} - -.outer { - position: relative; - margin: auto; - width: 70px; - margin-top: 0px; - cursor: pointer; -} - -.close { - position: absolute; - right: 20px; - top: 20px; - cursor: pointer; - display: none; - -webkit-app-region: no-drag; -} - -.advancedToggle { - display:none; - background-color:#EFEFEF; - padding:10px 12px 12px 2px; - margin: 0px 0px 0px 10px; -} - -.highlight { - background-color:#ddeeff; -} - -/*https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/*/ -input[type=range] { - -webkit-appearance: none; - margin: 18px 0; - width: 100%; -} -input[type=range]:focus { - outline: none; -} -input[type=range]::-webkit-slider-runnable-track { - width: 100%; - height: 8.4px; - cursor: pointer; - box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; - background: #3071a9; - border-radius: 1.3px; - border: 0.2px solid #010101; -} -input[type=range]::-webkit-slider-thumb { - box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; - border: 1px solid #000000; - height: 30px; - width: 16px; - border-radius: 3px; - background: #ffffff; - cursor: pointer; - -webkit-appearance: none; - margin-top: -11px; -} -input[type=range]:focus::-webkit-slider-runnable-track { - background: #367ebd; -} -input[type=range]::-moz-range-track { - width: 100%; - height: 8.4px; - cursor: pointer; - box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; - background: #3071a9; - border-radius: 1.3px; - border: 0.2px solid #010101; -} -input[type=range]::-moz-range-thumb { - box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; - border: 1px solid #000000; - height: 36px; - width: 16px; - border-radius: 3px; - background: #ffffff; - cursor: pointer; -} -input[type=range]::-ms-track { - width: 100%; - height: 8.4px; - cursor: pointer; - background: transparent; - border-color: transparent; - border-width: 16px 0; - color: transparent; -} -input[type=range]::-ms-fill-lower { - background: #2a6495; - border: 0.2px solid #010101; - border-radius: 2.6px; - box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; -} -input[type=range]::-ms-fill-upper { - background: #3071a9; - border: 0.2px solid #010101; - border-radius: 2.6px; - box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; -} -input[type=range]::-ms-thumb { - box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; - border: 1px solid #000000; - height: 36px; - width: 16px; - border-radius: 3px; - background: #ffffff; - cursor: pointer; -} -input[type=range]:focus::-ms-fill-lower { - background: #3071a9; -} -input[type=range]:focus::-ms-fill-upper { - background: #367ebd; -} - -@media only screen and (max-height: 650px) { - body { - font-size: 0.9em; - } - .gowebcam { - padding: 5px; - margin: 5px; - } - .infoblob { - color: white; - width: 100%; - padding: 20px; - max-width: 1280px; - } - #qrcode img { - max-height: 150px; - } - .outer { - width: 50px; - } - .close { - top: 0px; - right: 0px; - } -} - -@media screen and (max-width: 768px) { - #popOutChat{ - display: none; - } -} - -@media only screen and (max-width: 650px) { - - .mainmenuclass { - display: inline-block; - } - .outer { - width: 50px; - } - .close { - top: 0; - right: 0; - } - select { - height: 30px; - font-size: 120%; - } - #reshare { - max-width: 650px !important; - font-size: 96% !important; - width: 300px !important; - } - .fa-paperclip { - display: none; - } - #copythisurl { - color: #DDD; - display: inline-block; - font-size: 75% !important; - } - #logoname { - font-size: 100%; - } - .column { - float: none !important; - padding: 15px 10px 1px 10px !important; - } - #videoSettings { - max-width: 100% !important; - min-width: 100% !important; - } - .videoMenu { - max-width: 100% !important; - min-width: 100% !important; - } - div.multiselect { - max-width: 100% !important; - min-width: 100% !important; - } - #headphonesDiv3 { - max-width: 100% !important; - min-width: 100% !important; - overflow: hidden !important; - } - #effectsDiv3 { - max-width: 100% !important; - min-width: 100% !important; - overflow: hidden !important; - } - #effectsDiv { - max-width: 100% !important; - min-width: 100% !important; - overflow: hidden !important; - } - #headphonesDiv { - max-width: 100% !important; - min-width: 100% !important; - overflow: hidden !important; - } - #outputSource { - width: 100% !important; - } - #outputSource3 { - width: 100% !important; - } - #audioSourceScreenshare { - max-width: 90% !important; - min-width: 90% !important; - overflow: hidden !important; - } - #videoSettings2 { - max-width: 90% !important; - min-width: 90% !important; - overflow: hidden !important; - } - #popupSelector { - padding: 20px 5px 0px 15px !important; - font-size: 92%; - width: 385px !important - } - .mobileHide{ - display:none !important; - } -} - -@media only screen and (max-height: 355px) { - #popupSelector { - padding: 0 !important; - } -} -@media only screen and (max-height: 330px) { - #popupSelector { - padding: 0 !important; - font-size: 92%; - } -} - -.popupSelector_constraints{ - margin:30px 9% 0 7%; -} -.popupSelector_constraints label{ - color:white; - text-shadow: 0px 0px 6px #000000FF; - font-weight: 700; -} -.tooltip { - position: relative; - display: inline-block; - border-bottom: 1px dotted black; -} -.tooltip .tooltiptext { - visibility: hidden; - width: 10em; - background-color: #9d5050; - color: #fff; - text-align: center; - /* padding: 5px 0; */ - border-radius: 10px; - position: absolute; - z-index: 1; - top: -10px; - font-family: "Lato", sans-serif; -} -.tooltip:hover .tooltiptext { - visibility: visible; -} -#screensharebutton.float2{ - background-color: #335c3a; -} -#screenshare2button.float2{ - background-color: #335c3a; -} -#popupSelector { - background: linear-gradient(6deg, rgba(221, 221, 221, 0) 4%, rgb(221, 221, 221, 0.2) 30%, rgba(120, 120, 100, .5) 100%); - transition: all 0.2s linear 0s; - padding: 20px 20px 0px 20px; - position: fixed; - top: 0px; - height: 90%; - width: 505px; - right: -400px; - overflow: auto; - z-index: 3; -} - -#audioSourceScreenshare { - display:block; - height: 60px; - min-width: 290px; - overflow: auto; - padding: 5px; - resize: both; -} - -p#audioScreenShare1 { - border: 1px solid #ccc; - display: inline-block; - background: #f3f3f3; - padding: 4px 10px 10px 10px; - text-align: left; -} - -#audioScreenShare1 > i { - display: inline-block; -} - -#audioScreenShare1 > span { - margin: 7px 0px; - text-align: left; - display: inline-block; -} - -h2 { - color: white; - -webkit-user-select: none; - /* Safari */ - -moz-user-select: none; - /* Firefox */ - -ms-user-select: none; - /* IE10+/Edge */ - user-select: none; - /* Standard */ -} - -.inner { - width: inherit; - text-align: center; -} - -.labelclass { - opacity: 0; - font-size: 1.1em; - line-height: 4em; - text-transform: uppercase; - transition: all .3s ease-in; - cursor: pointer; -} - -label { - color: #000; -} - -.inner:before, -.inner:after { - position: absolute; - content: ''; - height: 7px; - width: inherit; - background: #000; - left: 0; - font-weight: bold; - transition: all .3s ease-in; -} - -.inner:before { - top: 50%; - transform: rotate(45deg); -} - -.inner:after { - bottom: 50%; - transform: rotate(-45deg); -} - -.outer:hover .labelclass { - opacity: 1; -} - -.outer:hover .inner:before, -.outer:hover .inner:after { - transform: rotate(0); -} - -.outer:hover .inner:before { - top: 0; -} - -.outer:hover .inner:after { - bottom: 0; -} - -.advanced { - display: none !important; -} -#dropButton{ - font-size: 2em; - display: block; - margin: auto; - background-color: #5555; - width: 100px; - /* padding: 30px; */ - border-radius: 30px; - cursor:pointer; - color: #636363 -} -.fullcolumn { - float: left; - display: inline-block; - margin: 0 auto; - width: 100%; - text-align: center; - /* Add shadows to create the "card" effect */ -} - -.card { - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, .1); - background-color: #ddd; -} - -/* Create four equal columns that floats next to each other */ - - -.column { - display: inline-block; - margin: 1.8%; - min-width: 300px; - width: 20%; - padding: 25px; - height: 200px; - /* Should be removed. Only for demonstration */ - border-radius: 5px; - text-align: center; - font-size: 100%; - /* Add shadows to create the "card" effect */ - transition: box-shadow 0.1s ease-in-out; -} - - -/* On mouse-over, add a deeper shadow */ - -.column:hover { - box-shadow: 0 8px 16px 0 rgba(0, 0, 0, .3); -} - -.column:active { - box-shadow: 0 8px 16px 0 rgba(0, 0, 0, .5); -} - -.column>h2 { - color: black; -} - -@keyframes fading { - 0% { - opacity: 0 - } - 100% { - opacity: 1 - } -} - - -} -img { - border-radius: 5px 5px 0 0; - margin: 5px; -} - -/* Empty container that will replace the original container */ -#empty-container { - display: inline-block; - /*float: left;*/ - width: 20%; - min-width: 300px; - padding: 28px; - height: 200px; - /* Should be removed. Only for demonstration */ - - margin: 1.8%; - text-align: center; -} -#container-1 { - background-repeat: no-repeat; - background-size: 80px; - background-position: 50% 65%; - background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPGc+CiAgICAgIDxwYXRoIGQ9Im0xMC41LDU4LjloNDQuM2MyLjMsMCA0LjEtMS44IDQuMS00LjF2LTQ0LjNjMC0yLjMtMS44LTQuMS00LjEtNC4xaC00NC4zYy0yLjMsMC00LjEsMS44LTQuMSw0LjF2NDQuM2MwLDIuMiAxLjksNC4xIDQuMSw0LjF6bTQuMS00NC4zaDM2LjF2MzYuMWgtMzYuMXYtMzYuMXoiIGZpbGw9IiMwMDAwMDAiLz4KICAgICAgPHBhdGggZD0ibTEyMi42LDEwLjVjMC0yLjMtMS44LTQuMS00LjEtNC4xaC00NC4zYy0yLjMsMC00LjEsMS44LTQuMSw0LjF2NDQuM2MwLDIuMyAxLjgsNC4xIDQuMSw0LjFoNDQuM2MyLjMsMCA0LjEtMS44IDQuMS00LjF2LTQ0LjN6bS04LjIsNDAuMmgtMzYuMXYtMzYuMWgzNi4xdjM2LjF6IiBmaWxsPSIjMDAwMDAwIi8+CiAgICAgIDxwYXRoIGQ9Im0xMC41LDEyMi42aDQ0LjNjMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi00NC4zYzAtMi4zLTEuOC00LjEtNC4xLTQuMWgtNDQuM2MtMi4zLDAtNC4xLDEuOC00LjEsNC4xdjQ0LjNjMCwyLjIgMS45LDQuMSA0LjEsNC4xem00LjEtNDQuM2gzNi4xdjM2LjFoLTM2LjF2LTM2LjF6IiBmaWxsPSIjMDAwMDAwIi8+CiAgICAgIDxwYXRoIGQ9Im0xMTguNSw3MC4xaC00NC4zYy0yLjMsMC00LjEsMS44LTQuMSw0LjF2NDQuM2MwLDIuMyAxLjgsNC4xIDQuMSw0LjFoNDQuM2MyLjMsMCA0LjEtMS44IDQuMS00LjF2LTQ0LjNjMC0yLjItMS45LTQuMS00LjEtNC4xem0tNC4xLDQ0LjNoLTM2LjF2LTM2LjFoMzYuMXYzNi4xeiIgZmlsbD0iIzAwMDAwMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==) -} -#container-2 { - background-repeat: no-repeat; - background-size: 80px; - background-position: 50% 65%; - background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPHBhdGggZD0ibTExOC41LDEwLjVoLTEwOGMtMi4zLDAtNC4xLDEuOC00LjEsNC4xdjUxLjcgMjEuMWMwLDIuMyAxLjgsNC4xIDQuMSw0LjFoNDkuOXYxOC44aC0yMi45Yy0yLjMsMC00LjEsMS44LTQuMSw0LjFzMS44LDQuMSA0LjEsNC4xaDU0YzIuMywwIDQuMS0xLjggNC4xLTQuMXMtMS44LTQuMS00LjEtNC4xaC0yMi45di0xOC44aDQ5LjljMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi0yMS4xLTUxLjdjMC0yLjMtMS44LTQuMS00LjEtNC4xem0tNC4xLDcyLjhoLTk5Ljh2LTEzaDk5Ljh2MTN6bTAtMjEuMWgtOTkuOHYtNDMuNWg5OS44djQzLjV6IiBmaWxsPSIjMDAwMDAwIi8+CiAgPC9nPgo8L3N2Zz4K) -} -#container-3 { - background-repeat: no-repeat; - background-size: 80px; - transition: background-image 0.3s ease-in-out; - -webkit-transition: background-image 0.3s ease-in-out; - background-position: 50% 65%; - background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPHBhdGggZD0ibTk2LjYsMjYuOGgtODYuMWMtMi4yLDAtNC4xLDEuOC00LjEsNC4xdjY3LjJjMCwyLjIgMS44LDQuMSA0LjEsNC4xaDg2LjFjMi4yLDAgNC4xLTEuOCA0LjEtNC4xdi0xOS40bDE0LjksMTQuOWMwLjgsMC44IDEuOCwxLjIgMi45LDEuMiAwLjUsMCAxLjEtMC4xIDEuNi0wLjMgMS41LTAuNiAyLjUtMi4xIDIuNS0zLjh2LTUyLjVjMC0xLjYtMS0zLjEtMi41LTMuOC0xLjUtMC42LTMuMy0wLjMtNC40LDAuOWwtMTQuOSwxNC45di0xOS4zYy0wLjEtMi4zLTEuOS00LjEtNC4yLTQuMXptLTQuMSwzMy4zdjguOCAyNS4yaC03OHYtNTkuMmg3OHYyNS4yem0yMS45LTEydjMyLjlsLTEzLjctMTMuN3YtNS40bDEzLjctMTMuOHoiIGZpbGw9IiMwMDAwMDAiLz4KICA8L2c+Cjwvc3ZnPgo=) -} -#container-4 { - background-repeat: no-repeat; - background-size: 80px; - background-position: 50% 65%; - background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgNDkwLjI4MiA0OTAuMjgyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0OTAuMjgyIDQ5MC4yODI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik0wLjA0MywyNDUuMTk3YzAuNiwxMC4xLDcuMywxOC42LDE3LDIxLjVsMTc5LjYsNTQuM2w2LjYsMTIzLjhjMC4zLDQuOSwzLjYsOS4yLDguMywxMC44YzEuMywwLjUsMi43LDAuNyw0LDAuNw0KCQljMy41LDAsNi44LTEuNCw5LjItNC4xbDYzLjUtNzAuM2w5MCw2Mi4zYzQsMi44LDguNyw0LjMsMTMuNiw0LjNjMTEuMywwLDIxLjEtOCwyMy41LTE5LjJsNzQuNy0zODAuN2MwLjktNC40LTAuOC05LTQuMi0xMS44DQoJCWMtMy41LTIuOS04LjItMy42LTEyLjQtMS45bC00NTksMTg2LjhDNS4xNDMsMjI1Ljg5Ny0wLjU1NywyMzUuMDk3LDAuMDQzLDI0NS4xOTd6IE0yMjYuMDQzLDQxNC4wOTdsLTQuMS03OC4xbDQ2LDMxLjgNCgkJTDIyNi4wNDMsNDE0LjA5N3ogTTM5MS40NDMsNDIzLjU5N2wtMTYzLjgtMTEzLjRsMjI5LjctMjIyLjJMMzkxLjQ0Myw0MjMuNTk3eiBNNDMyLjE0Myw3OC4xOTdsLTIyNy4xLDIxOS43bC0xNzkuNC01NC4yDQoJCUw0MzIuMTQzLDc4LjE5N3oiLz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjwvc3ZnPg0K) -} -#container-5 { - background-repeat: no-repeat; - background-size: 80px; - background-position: 50% 65%; - background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPGc+CiAgICAgIDxwYXRoIGQ9Im0xOC43LDEyMi41aDkxLjZjMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi0xMDcuOWMwLTIuMy0xLjgtNC4xLTQuMS00LjFoLTY4LjdjLTAuMywwLTAuNywwLTEsMC4xLTAuMSwwLTAuMiwwLjEtMC4yLDAuMS0wLjMsMC4xLTAuNSwwLjItMC44LDAuMy0wLjEsMC4xLTAuMiwwLjEtMC4zLDAuMi0wLjMsMC4yLTAuNiwwLjQtMC44LDAuN2wtMjIuOSwyN2MtMC4zLDAuMy0wLjUsMC43LTAuNywxLjEtMC4xLDAuMS0wLjEsMC4zLTAuMSwwLjQtMC4xLDAuMy0wLjEsMC42LTAuMiwwLjkgMCwwLjEgMCwwLjEgMCwwLjJ2ODAuOWMtMS4wNjU4MWUtMTQsMi40IDEuOSw0LjIgNC4xLDQuMnptMTguOC0xMDAuOHYxMS44aC0xMGwxMC0xMS44em0tMTQuNywxOS45aDE4LjhjMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi0yMi45aDYwLjV2OTkuN2gtODMuNHYtNzIuN3oiIGZpbGw9IiMwMDAwMDAiLz4KICAgICAgPHBhdGggZD0ibTk0LDUwLjVoLTU5Yy0yLjMsMC00LjEsMS44LTQuMSw0LjEgMCwyLjMgMS44LDQuMSA0LjEsNC4xaDU5YzIuMywwIDQuMS0xLjggNC4xLTQuMSAwLTIuMy0xLjgtNC4xLTQuMS00LjF6IiBmaWxsPSIjMDAwMDAwIi8+CiAgICAgIDxwYXRoIGQ9Im05NCw3MC4zaC01OWMtMi4zLDAtNC4xLDEuOC00LjEsNC4xIDAsMi4zIDEuOCw0LjEgNC4xLDQuMWg1OWMyLjMsMCA0LjEtMS44IDQuMS00LjEgMC0yLjItMS44LTQuMS00LjEtNC4xeiIgZmlsbD0iIzAwMDAwMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==) -} - -#container-6 { - -} - -#container-7 { - -} -.container-inner { - display: none; - background-color: rgb(221, 221, 221); - max-height: 100%; - min-height: 90%; -} -#add_screen { - padding-bottom: 20px; -} -.float { - opacity: 0.8; - min-width: 45px; - height: 45px; - background-color: #6666; - color: #FFF; - border-radius: 38px; - text-align: center; - margin: 5px; - pointer-events: auto; - outline:none; -} -.float2 { - opacity: 0.8; - width: 45px; - height: 45px; - background-color: #8888; - color: #FFF; - border-radius: 38px; - text-align: center; - z-index: 10; - margin: 5px; - pointer-events: auto; - outline:none; -} - -.rotate225 { - transform: rotate(135deg); - position: relative; - top: 1px; -} -.myVideo { - box-shadow: rgb(88, 88, 88) 0px 0px 5px 1px; - max-width: 800px !important; - max-height: 100% !important; - height: auto !important; - display: block !important; - margin: auto auto !important; - position: relative !important; - top: 50% !important; -} -#calendarButton { - cursor: pointer; - z-index: 6; - display:none; -} -#translateButton { - cursor: pointer; - z-index: 6; -} -#helpButton { - cursor: pointer; - z-index: 6; -} - -.popup .menu { margin: 2px; } - -.my-float { - margin-top: 7px; - opacity: 0.9; -} -.toggleSize { - font-size: 32px; - color: white; -} - -img { - max-width: 100%; -} -.in-animation { - animation: inlightbox 0.5s forwards; - position: fixed !important; - margin: 0 !important; -} - -.skip-animation { - position: fixed !important; - margin: 0 !important; - height: 100%; - width: 100%; - top: 0; - left: 0; -} -.skip-animation .container-inner{ - display:block; -} - -.out-animation { - animation: outlightbox 0.5s forwards; -} - -.pointer { - cursor: pointer; -} -@keyframes inlightbox { - 50% { - width: 100%; - left: 0; - height: 200px; - } - - 100% { - height: 100%; - width: 100%; - top: 0; - left: 0; - } -} -.column_neon { - color: white; - animation: neonGlow 2s infinite alternate cubic-bezier(0.455, 0.03, 0.515, 0.955); - box-shadow: 0 0 5px rgba(255, 255, 255, .8), 0 0 10px rgba(255, 255, 255, .8), 0 0 20px rgba(66, 220, 219, .5), 0 0 22px rgba(66, 220, 219, .5) -} -@keyframes neonGlow { - 100% { - box-shadow: 0 0 5px rgba(255, 255, 255, .8), 0 0 10px rgba(255, 255, 255, .8), 0 0 20px rgba(66, 220, 219, .5), 0 0 22px rgba(66, 220, 219, .5) - } - - 0% { - box-shadow: 0 0 2px rgba(255, 255, 255, .8), 0 0 3px rgba(255, 255, 255, .8), 0 0 4px rgba(66, 220, 219, .5) - } -} -.modal { - display: none; - position: fixed; - padding-top: 50px; - left: 0; - top: 0; - width: 100%; - height: 100%; - background-color: rgb(0, 0, 0); - background-color: rgba(0, 0, 0, 0.5); -} -.modal-content { - position: relative; - background-color: white; - padding: 20px; - margin: auto; - max-width: 400px; -} -.close-btn { - float: right; - color: lightgray; - font-size: 24px; - font-weight: bold; -} -.close-btn:hover { - color: darkgray; -} -#chattoggle{ - top: 0.5px; - position: relative; -} - -.la-phone { - color: red; - top:0.5; -} - -.ondeck { - border: grey solid 2px !important; -} - -.recording{ - border: red solid 2px !important; -} - -.onair { - display: block !important; -} - -.raisedHand{ - background-color: #DD1A !important; -} - -@-webkit-keyframes animatetop { - from { - top: -300px; - opacity: 0 - } - - to { - top: 0; - opacity: 1 - } -} -@keyframes animatetop { - from { - top: -300px; - opacity: 0 - } - - to { - top: 0; - opacity: 1 - } -} -#request_info_prompt{ - z-index: 20; - color: white; - font-size: 30px; - font-size: 3.5vw; - top: 0; - align-self: center; - margin: 25vh 0; - position: absolute; -} - -.holder { - position: relative; - width: 100%; - height: 100%; - max-width: 100%; - max-height: 100%; - margin: auto; - object-fit: contain; - display: flex; - align-items: center; - justify-content: center; - pointer-events: none; -} - -.fadein { - animation: fadeIn var(--fadein-speed); - -webkit-animation: fadeIn var(--fadein-speed); - -moz-animation: fadeIn var(--fadein-speed); - -o-animation: fadeIn var(--fadein-speed); - -ms-animation: fadeIn var(--fadein-speed); -} - - - -@keyframes fadeIn { - 0% {opacity:0;} - 100% {opacity:1;} -} - -@-moz-keyframes fadeIn { - 0% {opacity:0;} - 100% {opacity:1;} -} - -@-webkit-keyframes fadeIn { - 0% {opacity:0;} - 100% {opacity:1;} -} - -@-o-keyframes fadeIn { - 0% {opacity:0;} - 100% {opacity:1;} -} - -@-ms-keyframes fadeIn { - 0% {opacity:0;} - 100% {opacity:1;} -} - -video { - transition: opacity .25s ease-in-out; - -moz-transition: opacity .25s ease-in-out; - -webkit-transition: opacity .25s ease-in-out; - pointer-events: auto; - background-color: transparent !important; - border: 0; - margin: 0; - user-select:none; - -webkit-user-select: none; /* Chrome/Safari */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* IE10+ */ - -webkit-tap-highlight-color:transparent; - outline-style:none; - background-size: auto 50px; - background-repeat: no-repeat; - background-position: center; - background-image: url("data:image/svg+xml,%3Csvg viewBox='-42 0 512 512.002' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m210.351562 246.632812c33.882813 0 63.222657-12.152343 87.195313-36.128906 23.972656-23.972656 36.125-53.304687 36.125-87.191406 0-33.875-12.152344-63.210938-36.128906-87.191406-23.976563-23.96875-53.3125-36.121094-87.191407-36.121094-33.886718 0-63.21875 12.152344-87.191406 36.125s-36.128906 53.308594-36.128906 87.1875c0 33.886719 12.15625 63.222656 36.132812 87.195312 23.976563 23.96875 53.3125 36.125 87.1875 36.125zm0 0'/%3E%3Cpath d='m426.128906 393.703125c-.691406-9.976563-2.089844-20.859375-4.148437-32.351563-2.078125-11.578124-4.753907-22.523437-7.957031-32.527343-3.308594-10.339844-7.808594-20.550781-13.371094-30.335938-5.773438-10.15625-12.554688-19-20.164063-26.277343-7.957031-7.613282-17.699219-13.734376-28.964843-18.199219-11.226563-4.441407-23.667969-6.691407-36.976563-6.691407-5.226563 0-10.28125 2.144532-20.042969 8.5-6.007812 3.917969-13.035156 8.449219-20.878906 13.460938-6.707031 4.273438-15.792969 8.277344-27.015625 11.902344-10.949219 3.542968-22.066406 5.339844-33.039063 5.339844-10.972656 0-22.085937-1.796876-33.046874-5.339844-11.210938-3.621094-20.296876-7.625-26.996094-11.898438-7.769532-4.964844-14.800782-9.496094-20.898438-13.46875-9.75-6.355468-14.808594-8.5-20.035156-8.5-13.3125 0-25.75 2.253906-36.972656 6.699219-11.257813 4.457031-21.003906 10.578125-28.96875 18.199219-7.605469 7.28125-14.390625 16.121094-20.15625 26.273437-5.558594 9.785157-10.058594 19.992188-13.371094 30.339844-3.199219 10.003906-5.875 20.945313-7.953125 32.523437-2.058594 11.476563-3.457031 22.363282-4.148437 32.363282-.679688 9.796875-1.023438 19.964844-1.023438 30.234375 0 26.726562 8.496094 48.363281 25.25 64.320312 16.546875 15.746094 38.441406 23.734375 65.066406 23.734375h246.53125c26.625 0 48.511719-7.984375 65.0625-23.734375 16.757813-15.945312 25.253906-37.585937 25.253906-64.324219-.003906-10.316406-.351562-20.492187-1.035156-30.242187zm0 0'/%3E%3C/svg%3E"); -} - -.nogb { background-image: unset !important } - -video::-webkit-media-controls-timeline { - display: none; -} - -video::-webkit-media-controls-timeline-container { - display: none; -} - -audio::-webkit-media-controls-overlay-play-button, video::-webkit-media-controls-overlay-play-button { - display: none; -} - -audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button { - display: none; -} - -video::-webkit-media-controls-toggle-closed-captions-button { - display: none; -} - -video.clean::-webkit-media-controls-current-time-display { - display: inherit; -} - -video.clean::-webkit-media-controls-time-remaining-display { - display: inherit; -} - -video.clean::-webkit-media-controls-timeline { - display: inherit; -} - -video.clean::-webkit-media-controls-timeline-container { - display: inherit; -} - -.mirrorControl::-webkit-media-controls-enclosure { - padding: 0px; - height: 30px; - transform: scaleX(-1); - -webkit-transform: scaleX(-1); -} -.popup-screen { - align-text: center; - position: absolute; - display:none; - top:0; - left:0; - z-index: 7 !important; - padding: 20px; - margin:15px 15px 80px 15px; - width: 80vh !important; - height: 80vh !important; - background-color: #ccc !important; - border: solid 1px #dfdfdf !important; - box-shadow: 1px 1px 2px #cfcfcf !important; -} -.context-menu { - display: none; - position: absolute; - z-index: 10 !important; - padding: 12px 0 !important; - width: 240px !important; - background-color: #fff !important; - border: solid 1px #dfdfdf !important; - box-shadow: 1px 1px 2px #cfcfcf !important; -} -.popup-message { - display: none; - align-text: center; - position: absolute; - z-index: 21 !important; - padding: 3px !important; - min-width: 180px !important; - background-color: #fff !important; - border: solid 1px #dfdfdf !important; - box-shadow: 1px 1px 2px #cfcfcf !important; -} -.context-menu--active { - display: block !important; -} -.context-menu__items { - list-style: none !important; - margin: 0; - padding: 0; -} -.context-menu__item { - display: block; - margin-bottom: 4px !important; -} -.context-menu__item:last-child { - margin-bottom: 0 !important; -} -.context-menu__link { - display: block; - padding: 4px 12px; - color: #0066aa !important; - text-decoration: none; -} -.context-menu__link:hover { - color: #fff !important; - background-color: #0066aa !important; -} -.audioTitle { - text-align: left; - padding: 7px 0px; -} -.audioTitle2 { - text-align: left; - padding: 0px 10px 10px 1px; -} -.multiselect .multiselect-trigger:hover { - cursor: pointer; - cursor: hand; - text-decoration: none; -} -.multiselect .multiselect-trigger.open { - border-bottom: 0; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} -.multiselect .multiselect-trigger.closed { - border-bottom: 1px solid #ccc; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; -} -#headphonesDiv3 { - text-align: left; - margin: 17px 0 0 0; - width: 450px; - background-color: #f3f3f3; - padding: 10px 10px; - border: 1px solid #ccc; - vertical-align: middle; -} -#headphonesDiv { - text-align: left; - margin: 17px 0; - width: 450px; - background-color: #f3f3f3; - padding: 10px 10px; - border: 1px solid #ccc; - vertical-align: middle; -} - -#effectSelector3{ - background-color: #FFF; - display: inline-block; - vertical-align: middle; - padding: 3px; - font-size: 93%; - max-width: 100%; - width: 90%; -} - -#effectsDiv3 { - text-align: left; - width: 450px; - background-color: #f3f3f3; - padding: 10px 10px; - border: 1px solid #ccc; - vertical-align: middle; - margin: 17px 0 0 0; -} -#videoSettings { - margin: auto auto; - background-color: #f3f3f3; - width: 450px; - padding: 10px 0; - margin: 0px 0 0px 0; - border: 1px solid #ccc; -} -#audioMenu { - margin: 15px 0 0 0; -} - -#videosource { - display: inline-block; - vertical-align: middle; - font-size: 100%; -} -#videoSourceSelect { - display: inline-block; - vertical-align: middle; - font-size: 100%; - max-width: 260px; -} -#effectSelector{ - display: inline-block; - vertical-align: middle; - font-size: 100%; - max-width: 260px; -} -.gone { - position: absolute; - display: inline-block; - left: -9999px; -} -.grabLinks { - display: inline-flex; - cursor: grab; - font-weight: bold; - font-size: 1em; - padding: 10px; - margin: 5px 0; - word-break: break-all; -} -.grabLinks a:hover { - color: black !important; -} -.grabLinks a:active { - color: black !important; -} -.grabLinks a:link { - color: black !important; -} - -.hidden { - display:none; - visibility: hidden; - width:0px; - height:0px; -} -/* visited link */ -.grabLinks a:visited { - color: black !important; -} -#videoSettings3 { - margin: 0 auto 15px auto; - background-color: #f3f3f3; - width: 450px; - padding: 7px 10px 1px 10px; - border: 1px solid #ccc; - font-size: 90%; -} -#videoSource3 { - background-color: #FFF; - display: inline-block; - vertical-align: middle; - padding: 3px; - font-size: 93%; - max-width: 370px; -} -#outputSource { - background-color: #FFF; - display: inline-block; - vertical-align: middle; - padding: 4px; - font-size: 93%; - max-width: 100%; -} -#outputSource3 { - background-color: #FFF; - display: inline-block; - vertical-align: middle; - padding: 3px; - font-size: 93%; - max-width: 100%; -} -.videoMenu { - background-color: #f3f3f3; - width: 450px; - display: inline-block; - padding: 10px 10px; - border: 1px solid #ccc; - vertical-align: middle; - text-align: left; -} - -div.multiselect { - width: 450px; - white-space: nowrap; - overflow: hidden; - margin: auto auto; - border: 1px solid #ccc; - border-bottom: 0; - display: inline-block; - padding: 4px 10px 10px 10px; - background-color: #f3f3f3; -} -.multiselect .multiselect-contents { - display: block; - margin: 0; - font-size: 80%; - padding: 3px 5px 1px; - border-top: 0; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - text-align: left; - background-color: white; -} -.multiselect .multiselect-contents li { - list-style: none; - font-size: 120%; - padding: 2px; - overflow: hidden; -} -.select .select-trigger:hover { - cursor: pointer; - cursor: hand; - text-decoration: none; -} -.select .select-trigger.open { - border-bottom: 0; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} -.select .select-trigger.closed { - border-bottom: 1px solid #ccc; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; -} -.select .select-contents { - display: none; - margin: 0; - padding: 0 24px 24px; - border: 1px solid #ccc; - border-top: 0; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; -} -.select .select-contents li { - list-style: none; -} -::-webkit-input-placeholder { - color: #555 !important; -} -::-moz-placeholder { - color: #555 !important; -} -:-ms-input-placeholder { - color: #555 !important; -} -:-moz-placeholder { - color: #555 !important; -} -label { - font-weight: normal; -} -input[type=checkbox] { - /* Double-sized Checkboxes */ - - -ms-transform: scale(1.4); - /* IE */ - - -moz-transform: scale(1.4); - /* FF */ - - -webkit-transform: scale(1.4); - /* Safari and Chrome */ - - -o-transform: scale(1.4); - /* Opera */ - - transform: scale(1.4); - padding: 5px; - margin: 0 5px 0 1px; -} -#screenshare { - height: 300px; - display: inline-block; - max-height: 50vh; - max-width: 50vh; - border: 0; - margin: 0; - padding: 0; - text-shadow: 0; - box-shadow: 0; - text-decoration: none; - border-image-width: 0; - background-size: contain; - background-color: rgba(0, 0, 0, 0); -} -.inMessage { - color: #000; - margin: 3px; - border-radius: 5px; - background: #FFF; - padding: 5px; - text-align: left; - margin: 10px 3px; -} -.outMessage { - color: #000; - margin: 3px; - border-radius: 5px; - background: #BCF; - padding: 5px; - text-align: right; - margin: 10px 3px; -} -#chatBody { - z-index: 12; - background-color: #0004; - width: 100%; - border-radius: 5px; - padding: 1px 7px; - overflow-y:scroll; - overflow-wrap: anywhere; - max-height: 800px; -} - -#chatBody::-webkit-scrollbar { - width: 0px; - background: transparent; /* make scrollbar transparent */ -} - -#chatModule { - bottom: 50px; - position: fixed; - margin: 10px; - align-self: center; - width: 400px; - max-width: 100%; -} -#chatInput { - color: #000; - background-color: #FFFE; - max-width: 700px; - min-width: 320px; - font-size: 105%; - margin-left: 7px; - padding: 3px; - border: 3px solid black; -} -.debugStats { - font-size: 0.8rem; - list-style-type: none; - left: 50px; - top: 0px; - width: 300px; - min-height: 200px; - max-height: 99vh; - overflow-y: auto; - background-color: rgba(0, 0, 0, 0.95); - position: absolute; - z-index: 20; - color: white; - padding: 20px; - border: 2px solid #1d1d1d; -} -.debugStats::-webkit-scrollbar { - width: 0.5em; -} -.debugStats::-webkit-scrollbar-track { - background: black; - border-radius: 10px; -} - -/* Handle */ -.debugStats::-webkit-scrollbar-thumb { - background: rgb(119, 119, 119); - border-radius: 10px; -} - -/* Handle on hover */ -.debugStats::-webkit-scrollbar-thumb:hover { - background: rgb(158, 158, 158); - ; -} -.debugStats h1 { - font-size: 1rem; - text-align: left; - text-transform: uppercase; - margin-bottom: 10px; - margin-top: -5px; -} -.debugStats h2 { - font-size: 0.8rem; - text-align: left; - text-transform: uppercase; - margin-top: 10px; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - overflow: hidden; -} -.viewstats::-webkit-scrollbar-track { - box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); -} -.debugStats li { - display: flex; - margin: 5px 0px; -} -.debugStats li:nth-child(even) { - background: rgba(33, 33, 33, 0.8); - padding: 2px 0px; -} -.debugStats li span:first-child { - flex: 1; -} -.debugStats li span:last-child { - flex: 1; - text-align: right; -} -.debugStats .close { - font-weight: bold; - color: white; - display: block; - background: none; - padding: 0; - margin: 0; - font-size: 1.5rem; - border: none; - top: 10px; - right: 10px; -} -.debugStats button:not(.close) { - margin: 10px 0px; - padding: 10px 0px; - background: #263250; - color: white; - border-radius: 0; - width: 100%; - font-weight: bold; - border-bottom: 2px solid #364c84; -} -@media only screen and (max-width: 390px) { - #chatBody { - z-index: 12; - background-color: #FFF1; - width: 100%; - border-radius: 5px; - padding: 1px 7px; - margin: 0px; - } - - #chatModule { - bottom: 50px; - position: fixed; - margin: 0px; - align-self: center; - width: 400px; - max-width: 100%; - } - - #chatInput { - max-width: 99%; - min-width: 240px; - margin-left: 11px; - font-size: 100%; - } -} -.directorMargins { - margin: var(--director-margin); -} -.hideLinksClass { - background-color: var(--container-color); - width:1191px; - padding: 10px; - margin: 10px; -} -.directorContainer { - background-color: var(--container-color); - display: grid; - grid-template-columns: 1fr ; - margin: 10px 0px 10px 10px; - padding: 10px; - max-width: 1191px -} -@media only screen and (max-width: 390px) { - -} - -#directorLinksButton{ - cursor:pointer; -} -.directorContainer.half { - background-color: var(--container-color); - display: grid; - grid-template-columns: 1fr 1fr; - padding: 10px 10px; - width: 591px; -} -.directorBlock { - padding: 10px 10px 5px 10px; - margin: var(--regular-margin); - color: white; - position:relative; - max-width: 100%; - overflow: hidden; -} -.directorBlock:nth-child(1) { - background-color: var(--blue-accent); -} -.directorBlock:nth-child(2) { - background-color: var(--green-accent); -} -.directorBlock:nth-child(3) { - background-color: var(--olive-accent); -} -.directorBlock:nth-child(4) { - background-color: var(--red-accent); -} -.directorBlock button { - bottom: 0; - margin: 10px; -} -.directorBlock button i { - margin-right: 5px; -} -.task { - color: #808080; - width: 100%; - margin-top: 10px; -} -.directorBlock h2 { - text-transform: uppercase; - margin-bottom: 10px; - margin-left: 5px; - font-size:1.2em; -} -#toggleroomnotes { - grid-column: 4; - grid-row: 1; -} -div#roomnotes2 { - background: var(--container-color); - padding: 10px !important; - margin: 0 var(--regular-margin) 10px var(--regular-margin); - width: 100%; -} -.directorsgrid .directorContainer:nth-child(2) button { - grid-row: 1; - grid-column: 4; -} -.directorsgrid .directorContainer:nth-child(2) span { - grid-row: 1; - grid-column: 1; -} -.directorsgrid button { - text-transform: lowercase; -} -.controlsGrid { - grid-template-columns: 1fr 1fr; - display: grid; -} -.controlsGrid button { - margin: 5px; - text-align: right; -} -.controlsGrid span button { - margin-right: 0; - padding-left: 3px; - text-align: right; -} -.controlsGrid input { - margin: 5px var(--regular-margin); -} - -.pull-right { - float: right; - right: 0; -} -.pull-left { - float: left; - left: 0; -} -i.las.la-circle { - color: red; -} -.streamID { - text-align: right; - margin: 5px; - font-size: 0.7em; - text-overflow: ellipsis; - overflow: hidden; -} -.streamID i { - margin-left: 5px; - font-size: 1.3em; - position: relative; - top: 2px; -} -.soloLink { - background: none; - border-radius: 0; - width: 100%; - cursor: grab; - white-space: nowrap; - text-overflow: ellipsis; - font-size: 1.2em; - font-weight: 700; -} -.vidcon>h2 { - font-size: 1em; - margin-top: 20px; -} -div#guestFeeds { - background: var(--container-color); - padding: 5px 0 15px 20px; - display: inline-block; - margin: 0px var(--regular-margin); -} - -div#guestFeeds:empty { - display:none; -} - -#press2talk[data-enabled="true"] { - background: #1e0000; - -webkit-box-shadow: inset 0px 0px 1px #b90000; - -moz-box-shadow: inset 0px 0px 1px #b90000; - box-shadow: inset 0px 0px 1px #b90000; - outline: none; -} - -/* Top of the page share link */ -a#reshare { - white-space: nowrap; - margin: 0; - padding: 0; - display: inline; -} -#copythisurl+i { - display: inline; - font-size: 130%; -} - -/* Top of the page Join room input*/ -#joinroomID { - border-radius: 0; - padding: 5px; -} -#joinroomID+button { - margin: 0px var(--regular-margin); -} - -/* Tips for guests */ -span#guestTips { - margin: 0 auto 15px auto; - width: 450px; - display: flex; - flex-direction: column; - text-align: left; - background: #f3f3f3; - border: 1px solid #cccccc; - padding: 10px; -} - -#guestTips p { - font-weight: bold; - margin-bottom: 10px; -} - -#guestTips span:nth-child(1) { - color: red; -} - -#guestTips > span > i { - font-size: 2.5em; - margin-right: 10px; -} - -#guestTips > span > span { - line-height: 2.5em; - vertical-align: bottom; -} - -.video-label { - position: absolute; - bottom: 0.6vh; - left: 0.5vh; - margin: 0px; - color: white; - padding: 5px 10px; - background: rgba(0, 0, 0, .5); - font-size: 1em; - pointer-events:none; -} - - -.video-label.zoom { - bottom: 0; - left: 0; - pointer-events:none; -} - -.video-label.teams { - background: rgba(0, 0, 0, .4); - pointer-events:none; - border-radius: 5px; -} - -.video-label.skype { - bottom: 2vh; - left: 50%; - transform: translateX(-50%); - background: rgba(0, 0, 0, .8); - pointer-events:none; - border-radius: 5px; - font-size: 0.8em; -} - -.video-label.ninjablue { - bottom: 5%; - left: 0; - background: #141926; - padding: 10px 5%; -} - -.video-label.toprounded { - top: 0; - bottom: unset; - background: rgb(0 0 0 / 70%); - padding: 10px 5%; - left: 50%; - transform: translateX(-50%); - width: 50%; - text-align: center; - border-bottom-left-radius: 50px; - border-bottom-right-radius: 50px; - text-transform: uppercase; - letter-spacing: 3; - box-shadow: 0px 0px 10px #00000059; - font-size: 0.7em -} - -.video-label.fire { - text-shadow: 0 -1px 4px #FFF, 0 -2px 10px #ff0, 0 -10px 20px #ff8000, 0 -18px 40px #F00; - font-weight: bold; - bottom: 2vh; - left: 0; - width: 100%; - text-align: center; -} - -.video-meter { - padding:0.5vh; - display:block; - width:0.5vh; - height:0.5vh; - min-width:10px; - min-height:10px; - top: 2vh; - right: 2vh; - background-color:green; - position:absolute; - border-radius: 2vh; - pointer-events:none; - border: 1px black solid; -} -.video-meter-director { - width: 10px; - height: 10px; - top: 8px; - right: 10px; -} -.video-meter2 { - padding:0; - width: 4px; - height:0%; - min-width:2px; - bottom: 1px; - right: 5px; - background-color:#0000; - position:absolute; - border-radius: 2vh; - pointer-events:none; - border: 1px black solid; - transition: height 0.1s ease, background-color 0.1s ease; -} - -#voiceMeterTemplate{ - display:none; -} -#voiceMeterTemplate2{ - display:none; -} - -#userList{ - line-height: 1.3em; -} - -#userList > div > .video-meter { - padding: 5px; - margin-left: 5px; - top: 0; - right: 0; - position: relative; - display: inline-block; -} - -.video-mute-state { - top: 2vh; - right: 2vh; - position: absolute; - color:white; - border-radius: 2vh; - background-color:#b11313; - padding: 2px 2px 2px 1px; -} - -.video-mute-state-userlist { - display:inline-block; - color:white; - border-radius: 2vh; - background-color:#b11313; - padding: 2.2px 1.5px 2px 2px; - margin: 0 0 0 5px; -} - - -#help_directors_room{ - cursor:pointer; -} - -.iframeblob{ - padding-top:18px; - text-align: left; - width: 600px; - display: block; - margin: auto; -} -#shareScreenGear{ - display:none; -} - -div.message-card { - padding: 10px; - display: block; - padding-left: 1em; - align-items: center; - width: 600px; - margin: 0 auto; - position: relative; - padding-left: 60px; - margin: 0 auto; - margin-bottom: 20px; - box-shadow: 0px 5px 10px -5px #a9a9a9; -} - -div.message-card a { - color: rgb(0 77 218); - font-weight: bold; - text-decoration: underline; -} - -.warning.message-card { - border-left: 4px solid #eff150; - background: #fffded; -} -.info.message-card { - border-left: 4px solid #aacefd; - background: #e6e8f0; -} - -.message-card h1 { - display: block; - font-size: 110%; - text-align: left; -} - -.message-card p { - display: block; - text-align: left; - margin-top: 10px; -} - -div.message-card:before { - font-family: 'Line Awesome Free'; - font-weight: 900; - font-size: 2em; - margin-right: 0.5em; - position: absolute; - top: 6px; - left: 10px; -} - -div.message-card.warning:before { - content: "\f071"; -} - -div.message-card.info:before { - content: "\f05a"; -} - -@keyframes floating { - 0% { transform: translate(0, 0px); } - 50% { transform: translate(0, 15%); } - 100% { transform: translate(0, -0px); } -} - -.video-label.floating3d { - text-transform: uppercase; - display: block; - color: #FFFFFF; - text-shadow: 0 1px 0 #CCCCCC, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 10px 10px rgba(0,0,0,.2), 0 20px 20px rgba(0,0,0,.15); - color: #FFFFFF; - animation-name: floating; - animation-duration: 5s; - animation-iteration-count: infinite; - animation-timing-function: ease-in-out; - width: 100%; - font-size: 5em; - font-weight:bold; - text-align: center; - bottom: 4vh; - position: absolute; -} - -.director-link-icons { - font-size: 1.5em; - float: left; - bottom: 4px; - position: relative; - margin-right: 9px; -} - -.switch { - position: relative; - margin:5px 5px 2px 5px; - width: 40px; - height: 24px; - bottom:20px; - border-radius: 2px; - display: inline-block; -} - -.switch input { - width: 0; - height: 0; - opacity: 0; -} - -.slider { - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #ccc; - -webkit-transition: .3s; - transition: .3s; - position: absolute; -} - -.slider:before { - content: ""; - height: 17px; - width: 17px; - left: 3px; - bottom: 3px; - background-color: white; - -webkit-transition: .3s; - transition: .3s; - position: absolute; -} - -input:checked + .slider { - background-color: #86b98f; -} - -input:focus + .slider { - box-shadow: 0 0 1px #86b98f; -} - -input:checked + .slider:before { - -webkit-transform: translateX(16px); - -ms-transform: translateX(16px); - transform: translateX(16px); -} - - -#promptModal, #roomSettings { - position: absolute; - background-color: rgb(221 221 221); - box-shadow: 0 0 30px 10px #0000005c; - color: black; - font-size: 1.2em; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - border-radius: 10px; - font-weight: bold; - z-index:31; - min-width:400px; - max-width:90%; - overflow-wrap: break-word; -} - -.largeTextEntry { - width:300px; - margin: 0 0 0 55px; - font-size: 1em; - padding: 0.4em; - display: block; - -} -.promptModalInner { - position: relative; - padding: 1em; -} - -#iframe_source{ - width: 100%; - height: 100%; - margin: auto; - border: 10px dashed rgb(64 65 62) -} - -#SafariWarning{ - display:none; - width: 450px; - border-left: 4px solid #eff150; - background: #fffded; - padding: 10px; - align-items: center; - position: relative; - margin: 17px auto 20px auto; - box-shadow: 0px 5px 10px -5px #a9a9a9; - text-align: left; -} -#SafariWarning > p { - text-align: left; - display:inline-block; - padding-left: 38px; - -} -#SafariWarning > i { - position: absolute; - font-size: 2em; - padding: 2px 0 0 0; -} - -#alertModal { - position: absolute; - background-color: rgb(221 221 221); - box-shadow: 0 0 30px 10px #0000005c; - color: black; - font-size: 1.2em; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - border-radius: 10px; - font-weight: bold; - z-index:32; - min-width:360px; - max-width:90%; - overflow-wrap: break-word; -} - -#connectUsers{ - float: right; - display: none; - position: absolute; - max-width: 400px; - min-width: 150px; - max-height: 80%; - background-color: #08090e; - z-index: 5; - padding: 10px; - right: 20px; - bottom: 120px; - box-shadow: 2px 2px #313131; - border-radius: 5px; - border: 1px solid #252525; - opacity: 0.7; - color: white; -} - -#alertModal a:link { - color: blue; -} - -/* visited link */ -#alertModal a:visited { - color: blue; -} - -/* mouse over link */ -#alertModal a:hover { - color: blue; -} - -/* selected link */ - #alertModal a:active { - color: blue; -} - -.alertModalInner { - position: relative; - padding: 2em; -} - -.modalClose { - position: absolute; - top: -4px; - right: 4px; - cursor: pointer; - font-weight: bolder; - font-size: 1.8em; -} - -#modalBackdrop { - background: var(--background-color); - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 0; - opacity: 0.8; -} - -@media only screen and (max-width: 390px) { - .alertModal { - width: 90%; - } -} - -.desktop-capturer-selection { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100vh; - background: rgba(30,30,30,.75); - color: #fff; - z-index: 10000000; - display: flex; - align-items: center; - justify-content: center; -} -.desktop-capturer-selection__scroller { - width: 100%; - max-height: 100vh; - overflow-y: auto; -} -.desktop-capturer-selection__list { - max-width: calc(100% - 100px); - margin: 50px; - padding: 0; - display: flex; - flex-wrap: wrap; - list-style: none; - overflow: hidden; - justify-content: center; -} -.desktop-capturer-selection__item { - display: flex; - margin: 4px; -} -.desktop-capturer-selection__btn { - display: flex; - flex-direction: column; - align-items: stretch; - width: 145px; - margin: 0; - border: 0; - border-radius: 3px; - padding: 4px; - background: #252626; - text-align: left; - transition: background-color .15s, box-shadow .15s; -} -.desktop-capturer-selection__btn:hover, -.desktop-capturer-selection__btn:focus { - background: rgba(98,100,167,.8); -} -.desktop-capturer-selection__thumbnail { - width: 100%; - height: 81px; - object-fit: cover; -} -.desktop-capturer-selection__name { - margin: 6px 0 6px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; +:root { + --background-color: #141926; + --container-color: #373737; + --button-color: #2A2A2A; + --blue-accent: #4a4c63; + --red-accent: #553737; + --green-accent: #3f4f50; + --olive-accent: #535D32; + --regular-margin: 10px; + --director-margin: 15px 20px 0 0; + --fit-style: contain; + --fadein-speed: 0; + --video-margin: 0px; +} + +* { + padding: 0; + margin: 0; + box-sizing: border-box; + border: 0; +} + + +table { + display: inline-block; + padding:10px; + margin:10px; +} + +#bigPlayButton { + margin:0 auto; + background-color: #0000; + color: #; + font-family: Cousine, monospace; + font-size: 4em; + line-height: 1.5em; + letter-spacing: 0.0em; + text-shadow: 0.05em 0.05em 0px rgba(0,0,0,1); + width:100%; + height:100vh; + z-index: 1; + vertical-align: top; + text-align: center; + top: 0; + position: fixed; + overflow-wrap: anywhere; + padding:3%; + pointer-events: none +} + +#playButton { + font-size: 50vh; + border-radius: 50vh; + font-size: min(50vw, 50vh); + cursor:pointer; + opacity:100%; + margin-top: 20vh; + background-color:#444; +} + +tr { + padding:4px; +} +th { + padding:4px; +} + +.meter { + display: inline-block; + width: 0px; + height: 10px; + background: green; + transition: all 100ms linear; +} +.meter2 { + display: inline-block; + width: 0px; + height: 10px; + background: yellow; + transition: all 50ms linear; +} + +#mynetwork { + width: 600px; + height: 400px; + border: 1px solid lightgray; +} + +.email { + unicode-bidi: bidi-override; + direction: rtl; + user-select: none; +} + +a:link { + text-decoration: none; + color: #B9DFF9; +} + +/* visited link */ + +a:visited { + text-decoration: none; + color: #99BFD9; +} + + +/* mouse over link */ + +a:hover { + color: #048AE8; +} + + +/* selected link */ + +a:active { + color: #D9E4EB; +} + +input { + border-radius: 4px; + padding: 2px; + -webkit-app-region: no-drag; +} + +button.grey { + -webkit-app-region: no-drag; + padding: 10px; + margin: 10px 0px; + cursor: pointer; + border-radius: 2px; + background-color: var(--button-color); + color: white; +} + + +#miniPerformer>#videosource{ + width: 80px; + height: 45px; + margin: 5px; + background-color: #464749 !important; + background-size: 50%; +} + +#miniPerformer>#previewWebcam{ + width: 80px; + height: 45px; + margin: 5px; + background-color: #464749 !important; + background-size: 50%; +} + +#reportbutton{ + visibility: hidden; +} + +.red { + background-color: #840000 !important; +} + +button.red { + -webkit-app-region: no-drag; + padding: 10px; + margin: 10px 0px; + cursor: pointer; + border-radius: 2px; + color: white; +} + +button { + -webkit-app-region: no-drag; + padding: 7px 10px 6px 10px; + user-select: none; + margin: 10px 0px; + cursor: pointer; + border-radius: 2px; +} + + +button.white { + -webkit-app-region: no-drag; + padding: 6px 10px 4px 9px; + ; + margin: 10px 0px; + cursor: pointer; + border-radius: 2px; + background-color: white; + color: black; + border: 1px solid black; +} + +button.white:active { + -webkit-app-region: no-drag; + padding: 6px 10px 4px 9px; + ; + margin: 10px 0px; + cursor: pointer; + border-radius: 2px; + background-color: black; + color: white; + border: 1px solid black; +} + +#header { + width: 100%; + padding: 1px; + background-color: #0F131D; + color: #FFF; +} +#head5 { + display: inline-block; + text-decoration: none; + color: white; + text-align: right; + margin-right: 10px; + pointer-events: none; + float: right; +} + +#overlayMsgs{ + margin:0 auto; + background-color: #0000; + color: white; + font-family: Cousine, monospace; + font-size: 6vh; + line-height: 8vh; + letter-spacing: 0.0em; + text-shadow: 0.05em 0.05em 0px rgba(0,0,0,1); + width:100%; + height:100vh; + z-index: 7; + vertical-align: top; + text-align: center; + top: 0; + position: fixed; + overflow-wrap: anywhere; + padding:2% 3%; + pointer-events: none +} +#overlayMsgs span{ + background-color: #000B; + padding: 2px; + margin: 0.5vh; + text-align: center; + width:100%; + pointer-events: none +} + +.credits { + color: #101020; + position: fixed; + bottom: 0; + right: 0; + z-index: -1; + font-size: 80%; +} + +.credits>a { + color: #101020; +} + +.credits>a:visited { + color: #101020; +} + +.chevron { + padding: 0px 6px; +} + +.chevron::before { + border-style: solid; + border-width: 0.14em 0.14em 0 0; + content: ''; + display: inline-block; + height: 0.32em; + left: 0.15em; + position: relative; + top: .43em; + transform: rotate(-45deg); + vertical-align: top; + width: 0.32em; +} + +.chevron.bottom::before { + top: .28em; + transform: rotate(135deg); +} + +.chevron.right::before { + top: .28em; + transform: rotate(45deg); +} + +.label { + float: left; + font-size: 1.2em; + color: white; + display: inline-block; + position: absolute; + bottom: 0; + align-self: center; + z-index: 1000; + margin: 5% 20%; + padding: 1%; + background-color: black; +} + +.pressed { + background: #1e0000; + -webkit-box-shadow: inset 0px 0px 1px #b90000; + -moz-box-shadow: inset 0px 0px 1px #b90000; + box-shadow: inset 0px 0px 1px #b90000; + outline: none; + color: white; +} + +.row { + align-content: center; + text-align: center; + margin-top: 10px; +} + +hr { + height: 2px; + border-width: 0; + color: gray; + background-color: gray; +} + +.orderspan{ + font-size: 50%; + display: inline-block; + margin: auto; + text-align: center; + width: 49px; + height: 22px; + top: 5px; + position: relative; + user-select: none; +} +/* Clear floats after the columns */ + +.row:after { + content: ""; + display: table; + clear: both; +} + +.vidcon { + max-width: 100%; + border: 0; +} + +.vidcon:nth-of-type(3n) { + grid-column: 2; +} + +.vidcon:nth-of-type(3n) { + grid-row: span; +} + +.tile { + object-fit: var(--fit-style); + background-color: black; + width: 100%; + height: 100%; + border: 0; + padding: 0; + overflow: hidden; + margin: var(--video-margin); +} + +#gridlayout { + padding: 0; + width: 100%; + height: 100%; + grid-gap: 0; + overflow: hidden; + justify-items: stretch; + grid-auto-flow: dense; + grid-auto-columns: minmax(50%, auto); + grid-auto-rows: minmax(50%, auto); + border: 0; + margin: 0; +} + + +/* Invite link generator */ + +.invite_setting_group { + margin: 20px 0px; + background-color: #d2d2d2; + padding: 10px; +} + +.invite_setting_group h4 { + margin: 10px 0px 20px; +} + +.invite_setting_item { + margin: 10px 0px; +} + +.directorsgrid { + justify-items: normal; + grid-auto-columns: minmax(100px, 530px); + grid-auto-rows: minmax(100px, 300px); + display: block ! important; + overflow-y: auto !important; +} + +.directorsgrid .vidcon video { + margin: 0 5px; + padding:0; + width: 100%; + height: 148px; + max-width: 260px; +} + +.directorsgrid .vidcon { + display: inline-block !important; + width: 269.7px !important; + background: #7E7E7E; + color: #FCFCFC; + vertical-align: top; +} + +.directorsgrid .vidcon>.las { + color: black; + background: #999999; + width: 90%; +} + +.puslate { + border-radius: 50%; + box-shadow: 0 0 0 0 rgba(14, 19, 26, 1); + transform: scale(1); + animation: pulse 2s infinite; +} + +.mirror { + transform: scaleX(-1); +} + +.notification { + position: relative; + top: -40px; + right: -33px; + padding: 2px 0; + border-radius: 50%; + background: red; + color: white; + width: 11px; + height: 11px; + margin: 0; +} +.queueNotification { + position: relative; + top: -40px; + right: -33px; + padding: 2px 0; + border-radius: 50%; + background: #335c3a; + color: white; + width: 23px; + height: 23px; + margin: 0; +} + + +button.glyphicon-button:focus, +button.glyphicon-button:active:focus, +button.glyphicon-button.active:focus, +button.glyphicon-button.focus, +button.glyphicon-button:active.focus, +button.glyphicon-button.active.focus { + outline: none !important; +} + +#main { + -webkit-tap-highlight-color: rgba(255, 255, 255, 0) !important; + -webkit-tap-highlight-color: transparent !important; + outline: 0px !important; + height:100%; +} + +#controlButtons { + position: fixed; + z-index: 5; + bottom: 0px; + width: 100%; + display: none; + justify-content: center; + align-items: center; + height: 60px; + border: 0; + pointer-events: none; +} + +#subControlButtons { + display: flex; + border-radius: 38px; + background-color: #030303dd; + padding: 5px 7px; + position: absolute; + pointer-events: auto; +} +#container.vidcon { + height:100%; +} + +@media only screen and (max-width: 640px){ + #subControlButtons { + transform: scale(0.9) translateY(10%); + } +} +@media only screen and (max-width: 400px){ + #subControlButtons { + transform: scale(0.8) translateY(20%); + } +} +@media only screen and (max-width: 300px){ + #subControlButtons { + padding: 0px; + } +} + +@media only screen and (max-width: 620px){ + #obsState { + top: 10px !important; + transform: scale(0.9); + } +} +@media only screen and (max-width: 400px){ + #obsState { + top: 20px !important; + transform: scale(0.8); + } +} +@media only screen and (max-width: 300px){ + #obsState { + top: 30px !important; + transform: scale(0.7); + } +} +obsState + +/* Node selector to prioritise this selector above .float */ +button.btnArmTransferRoom{ + width:auto; + margin-left: 2px; + height:38px; + border-radius: 15px; +} +button.btnArmTransferRoom i{ + margin-right:3px; +} +button.btnArmTransferRoom:hover{ + background-color: var(--green-accent); +} + +button.btnArmTransferRoom.selected{ + background-color: #840000; +} + +@media only screen and (max-height: 540px){ + #subControlButtons { + transform: scale(0.88); + } + #gridlayout>#container.vidcon { + height:88% + } + #controlButtons { + height:54px; + } +} +@media only screen and (max-height: 500px){ + #subControlButtons { + transform: scale(0.87); + } + #gridlayout>#container.vidcon { + height:87% + } + #controlButtons { + height:54px; + } +} +@media only screen and (max-height: 400px){ + #subControlButtons { + transform: scale(0.85); + } + #logoname{ + display:none; + } + #head1{ + display:none; + } + #head4{ + display:none; + } + #head5{ + display:none; + } + #head2{ + display:none; + } + #gridlayout>#container.vidcon { + height:85% + } + #controlButtons { + height:50px; + } +} +@media only screen and (max-height: 300px){ + #gridlayout>#container.vidcon { + height:81% + } + #subControlButtons { + transform: scale(0.81); + } + #controlButtons { + height:46.2px; + } + #head2 { + display:none !important; + } +} +@media only screen and (max-height: 240px){ + #gridlayout>#container.vidcon { + height:78% + } + #subControlButtons { + transform: scale(0.77); + } + #controlButtons { + height:46.2px; + } +} +@media only screen and (max-height: 190px){ + #gridlayout>#container.vidcon { + height:75% + } + #subControlButtons { + transform: scale(0.73); + } + #controlButtons { + height:42px + } +} +@media only screen and (max-height: 160px){ + #gridlayout>#container.vidcon { + height:70% + } + #subControlButtons { + transform: scale(0.65); + } + #controlButtons { + height:38px + } +} +@media only screen and (max-height: 120px){ + #gridlayout>#container.vidcon { + height:70% + } + #subControlButtons { + transform: scale(0.52); + } + #controlButtons { + height:30px + } +} + +#header:empty{ + display:none; +} + +@keyframes pulse { + 0% { + transform: scale(1); + box-shadow: 0 0 0 0 rgba(14, 19, 26, 0.7); + } + 15% { + transform: scale(1.2); + box-shadow: 0 0 0 10px rgba(2, 3, 4, 0); + } + 50% { + transform: scale(1.0); + box-shadow: 0 0 0 0 rgba(14, 19, 26, 0); + } + 85% { + transform: scale(0.95); + box-shadow: 0 0 0 0 rgba(14, 19, 26, 0); + } + 100% { + transform: scale(1); + box-shadow: 0 0 0 0 rgba(14, 19, 26, 0); + } +} + +.la-sliders-h { + cursor:pointer; +} + +.la-sliders-h { + cursor:pointer; +} + +select { + cursor:pointer; +} + +input[type='checkbox'] { cursor:pointer; } +input[type='radio'] { cursor:pointer; } + +.icn-spinner { + animation: spin-animation 3s infinite; + display: inline-block; + z-index: 10; +} + +@keyframes spin-animation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(359deg); + } +} + +html { + border: 0; + margin: 0; + outline: 0; +} + +li { + margin: 0.1em 0; + padding-left: 0.1em; + line-height: 1.3em; +} + +body { + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + color: var(--gray90); + font-family: "Lato", sans-serif; + padding: 0 0px; + height: 100%; + width: 100%; + background-color: var(--background-color); + font-family: Helvetica, Arial, sans-serif; + display: flex; + flex-flow: column; + border: 0; + margin: 0; + opacity: 1; + transition: opacity .1s linear; +} + +.hidden { + visibility: hidden; + opacity: 0; +} + +.previewWebcam { + max-width: 640px; + max-width: 83vw; + height: 30vh; + opacity:1; + animation: fading 0.2s; +} + +#getPermissions{ + font-size: 110%; + border: 3px solid #99A; + cursor: pointer; + background-color: #cce0ff; + margin: 20px; + padding: 10px 50px; + text-align:center; +} + +.gowebcam { + font-size: 110%; + border: 3px solid #DDDDDD; + cursor: pointer; + background-color: #DDDDDD; + margin: 20px; + padding: 10px 50px; +} +.gowebcam:enabled { + background-color: #3C3 !important; + color: black; + font-weight: bold !important;; +} + +.mainmenuclass { + display: inherit; +} + +.gobutton { + font-size: 110%; + padding: 10px; + border: 3px solid #DDDDDD; + cursor: pointer; + background-color: #99BFD9; + color: black; + font-weight: bold; +} + +.infoblob { + color: white; + width: 100%; + padding: 20px; + max-width: 1280px; +} + +.outer { + position: relative; + margin: auto; + width: 70px; + margin-top: 0px; + cursor: pointer; +} + +.close { + position: absolute; + right: 20px; + top: 20px; + cursor: pointer; + display: none; + -webkit-app-region: no-drag; +} + +.advancedToggle { + display:none; + background-color:#EFEFEF; + padding:10px 12px 12px 2px; + margin: 0px 0px 0px 10px; +} + +.highlight { + background-color:#ddeeff; +} + +/*https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/*/ +input[type=range] { + -webkit-appearance: none; + margin: 18px 0; + width: 100%; +} +input[type=range]:focus { + outline: none; +} +input[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 8.4px; + cursor: pointer; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + background: #3071a9; + border-radius: 1.3px; + border: 0.2px solid #010101; +} +input[type=range]::-webkit-slider-thumb { + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + border: 1px solid #000000; + height: 30px; + width: 16px; + border-radius: 3px; + background: #ffffff; + cursor: pointer; + -webkit-appearance: none; + margin-top: -11px; +} +input[type=range]:focus::-webkit-slider-runnable-track { + background: #367ebd; +} +input[type=range]::-moz-range-track { + width: 100%; + height: 8.4px; + cursor: pointer; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + background: #3071a9; + border-radius: 1.3px; + border: 0.2px solid #010101; +} +input[type=range]::-moz-range-thumb { + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + border: 1px solid #000000; + height: 36px; + width: 16px; + border-radius: 3px; + background: #ffffff; + cursor: pointer; +} +input[type=range]::-ms-track { + width: 100%; + height: 8.4px; + cursor: pointer; + background: transparent; + border-color: transparent; + border-width: 16px 0; + color: transparent; +} +input[type=range]::-ms-fill-lower { + background: #2a6495; + border: 0.2px solid #010101; + border-radius: 2.6px; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; +} +input[type=range]::-ms-fill-upper { + background: #3071a9; + border: 0.2px solid #010101; + border-radius: 2.6px; + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; +} +input[type=range]::-ms-thumb { + box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; + border: 1px solid #000000; + height: 36px; + width: 16px; + border-radius: 3px; + background: #ffffff; + cursor: pointer; +} +input[type=range]:focus::-ms-fill-lower { + background: #3071a9; +} +input[type=range]:focus::-ms-fill-upper { + background: #367ebd; +} + +@media only screen and (max-height: 650px) { + body { + font-size: 0.9em; + } + .gowebcam { + padding: 5px; + margin: 5px; + } + .infoblob { + color: white; + width: 100%; + padding: 20px; + max-width: 1280px; + } + #qrcode img { + max-height: 150px; + } + .outer { + width: 50px; + } + .close { + top: 0px; + right: 0px; + } +} + +@media screen and (max-width: 768px) { + #popOutChat{ + display: none; + } +} + +@media only screen and (max-width: 650px) { + + .mainmenuclass { + display: inline-block; + } + .outer { + width: 50px; + } + .close { + top: 0; + right: 0; + } + select { + height: 30px; + font-size: 120%; + } + #reshare { + max-width: 650px !important; + font-size: 96% !important; + width: 300px !important; + } + .fa-paperclip { + display: none; + } + #copythisurl { + color: #DDD; + display: inline-block; + font-size: 75% !important; + } + #logoname { + font-size: 100%; + } + .column { + float: none !important; + padding: 15px 10px 1px 10px !important; + } + #videoSettings { + max-width: 100% !important; + min-width: 100% !important; + } + .videoMenu { + max-width: 100% !important; + min-width: 100% !important; + } + div.multiselect { + max-width: 100% !important; + min-width: 100% !important; + } + #headphonesDiv3 { + max-width: 100% !important; + min-width: 100% !important; + overflow: hidden !important; + } + #effectsDiv3 { + max-width: 100% !important; + min-width: 100% !important; + overflow: hidden !important; + } + #effectsDiv { + max-width: 100% !important; + min-width: 100% !important; + overflow: hidden !important; + } + #headphonesDiv { + max-width: 100% !important; + min-width: 100% !important; + overflow: hidden !important; + } + #outputSource { + width: 100% !important; + } + #outputSource3 { + width: 100% !important; + } + #audioSourceScreenshare { + max-width: 90% !important; + min-width: 90% !important; + overflow: hidden !important; + } + #videoSettings2 { + max-width: 90% !important; + min-width: 90% !important; + overflow: hidden !important; + } + #popupSelector { + padding: 20px 5px 0px 15px !important; + font-size: 92%; + width: 385px !important + } + .mobileHide{ + display:none !important; + } +} + +@media only screen and (max-height: 355px) { + #popupSelector { + padding: 0 !important; + } +} +@media only screen and (max-height: 330px) { + #popupSelector { + padding: 0 !important; + font-size: 92%; + } +} + +.popupSelector_constraints{ + margin:30px 9% 0 7%; +} +.popupSelector_constraints label{ + color:white; + text-shadow: 0px 0px 6px #000000FF; + font-weight: 700; +} +.tooltip { + position: relative; + display: inline-block; + border-bottom: 1px dotted black; +} +.tooltip .tooltiptext { + visibility: hidden; + width: 10em; + background-color: #9d5050; + color: #fff; + text-align: center; + /* padding: 5px 0; */ + border-radius: 10px; + position: absolute; + z-index: 1; + top: -10px; + font-family: "Lato", sans-serif; +} +.tooltip:hover .tooltiptext { + visibility: visible; +} +#screensharebutton.float2{ + background-color: #335c3a; +} +#screenshare2button.float2{ + background-color: #335c3a; +} +#popupSelector { + background: linear-gradient(6deg, rgba(221, 221, 221, 0) 4%, rgb(221, 221, 221, 0.2) 30%, rgba(120, 120, 100, .5) 100%); + transition: all 0.2s linear 0s; + padding: 20px 20px 0px 20px; + position: fixed; + top: 0px; + height: 90%; + width: 505px; + right: -400px; + overflow: auto; + z-index: 3; +} + +#audioSourceScreenshare { + display:block; + height: 60px; + min-width: 290px; + overflow: auto; + padding: 5px; + resize: both; +} + +p#audioScreenShare1 { + border: 1px solid #ccc; + display: inline-block; + background: #f3f3f3; + padding: 4px 10px 10px 10px; + text-align: left; +} + +#audioScreenShare1 > i { + display: inline-block; +} + +#audioScreenShare1 > span { + margin: 7px 0px; + text-align: left; + display: inline-block; +} + +h2 { + color: white; + -webkit-user-select: none; + /* Safari */ + -moz-user-select: none; + /* Firefox */ + -ms-user-select: none; + /* IE10+/Edge */ + user-select: none; + /* Standard */ +} + +.inner { + width: inherit; + text-align: center; +} + +.labelclass { + opacity: 0; + font-size: 1.1em; + line-height: 4em; + text-transform: uppercase; + transition: all .3s ease-in; + cursor: pointer; +} + +label { + color: #000; +} + +.inner:before, +.inner:after { + position: absolute; + content: ''; + height: 7px; + width: inherit; + background: #000; + left: 0; + font-weight: bold; + transition: all .3s ease-in; +} + +.inner:before { + top: 50%; + transform: rotate(45deg); +} + +.inner:after { + bottom: 50%; + transform: rotate(-45deg); +} + +.outer:hover .labelclass { + opacity: 1; +} + +.outer:hover .inner:before, +.outer:hover .inner:after { + transform: rotate(0); +} + +.outer:hover .inner:before { + top: 0; +} + +.outer:hover .inner:after { + bottom: 0; +} + +.advanced { + display: none !important; +} +#dropButton{ + font-size: 2em; + display: block; + margin: auto; + background-color: #5555; + width: 100px; + /* padding: 30px; */ + border-radius: 30px; + cursor:pointer; + color: #636363 +} +.fullcolumn { + float: left; + display: inline-block; + margin: 0 auto; + width: 100%; + text-align: center; + /* Add shadows to create the "card" effect */ +} + +.card { + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, .1); + background-color: #ddd; +} + +/* Create four equal columns that floats next to each other */ + + +.column { + display: inline-block; + margin: 1.8%; + min-width: 300px; + width: 20%; + padding: 25px; + height: 200px; + /* Should be removed. Only for demonstration */ + border-radius: 5px; + text-align: center; + font-size: 100%; + /* Add shadows to create the "card" effect */ + transition: box-shadow 0.1s ease-in-out; +} + + +/* On mouse-over, add a deeper shadow */ + +.column:hover { + box-shadow: 0 8px 16px 0 rgba(0, 0, 0, .3); +} + +.column:active { + box-shadow: 0 8px 16px 0 rgba(0, 0, 0, .5); +} + +.column>h2 { + color: black; +} + +@keyframes fading { + 0% { + opacity: 0 + } + 100% { + opacity: 1 + } +} + + +} +img { + border-radius: 5px 5px 0 0; + margin: 5px; +} + +/* Empty container that will replace the original container */ +#empty-container { + display: inline-block; + /*float: left;*/ + width: 20%; + min-width: 300px; + padding: 28px; + height: 200px; + /* Should be removed. Only for demonstration */ + + margin: 1.8%; + text-align: center; +} +#container-1 { + background-repeat: no-repeat; + background-size: 80px; + background-position: 50% 65%; + background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPGc+CiAgICAgIDxwYXRoIGQ9Im0xMC41LDU4LjloNDQuM2MyLjMsMCA0LjEtMS44IDQuMS00LjF2LTQ0LjNjMC0yLjMtMS44LTQuMS00LjEtNC4xaC00NC4zYy0yLjMsMC00LjEsMS44LTQuMSw0LjF2NDQuM2MwLDIuMiAxLjksNC4xIDQuMSw0LjF6bTQuMS00NC4zaDM2LjF2MzYuMWgtMzYuMXYtMzYuMXoiIGZpbGw9IiMwMDAwMDAiLz4KICAgICAgPHBhdGggZD0ibTEyMi42LDEwLjVjMC0yLjMtMS44LTQuMS00LjEtNC4xaC00NC4zYy0yLjMsMC00LjEsMS44LTQuMSw0LjF2NDQuM2MwLDIuMyAxLjgsNC4xIDQuMSw0LjFoNDQuM2MyLjMsMCA0LjEtMS44IDQuMS00LjF2LTQ0LjN6bS04LjIsNDAuMmgtMzYuMXYtMzYuMWgzNi4xdjM2LjF6IiBmaWxsPSIjMDAwMDAwIi8+CiAgICAgIDxwYXRoIGQ9Im0xMC41LDEyMi42aDQ0LjNjMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi00NC4zYzAtMi4zLTEuOC00LjEtNC4xLTQuMWgtNDQuM2MtMi4zLDAtNC4xLDEuOC00LjEsNC4xdjQ0LjNjMCwyLjIgMS45LDQuMSA0LjEsNC4xem00LjEtNDQuM2gzNi4xdjM2LjFoLTM2LjF2LTM2LjF6IiBmaWxsPSIjMDAwMDAwIi8+CiAgICAgIDxwYXRoIGQ9Im0xMTguNSw3MC4xaC00NC4zYy0yLjMsMC00LjEsMS44LTQuMSw0LjF2NDQuM2MwLDIuMyAxLjgsNC4xIDQuMSw0LjFoNDQuM2MyLjMsMCA0LjEtMS44IDQuMS00LjF2LTQ0LjNjMC0yLjItMS45LTQuMS00LjEtNC4xem0tNC4xLDQ0LjNoLTM2LjF2LTM2LjFoMzYuMXYzNi4xeiIgZmlsbD0iIzAwMDAwMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==) +} +#container-2 { + background-repeat: no-repeat; + background-size: 80px; + background-position: 50% 65%; + background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPHBhdGggZD0ibTExOC41LDEwLjVoLTEwOGMtMi4zLDAtNC4xLDEuOC00LjEsNC4xdjUxLjcgMjEuMWMwLDIuMyAxLjgsNC4xIDQuMSw0LjFoNDkuOXYxOC44aC0yMi45Yy0yLjMsMC00LjEsMS44LTQuMSw0LjFzMS44LDQuMSA0LjEsNC4xaDU0YzIuMywwIDQuMS0xLjggNC4xLTQuMXMtMS44LTQuMS00LjEtNC4xaC0yMi45di0xOC44aDQ5LjljMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi0yMS4xLTUxLjdjMC0yLjMtMS44LTQuMS00LjEtNC4xem0tNC4xLDcyLjhoLTk5Ljh2LTEzaDk5Ljh2MTN6bTAtMjEuMWgtOTkuOHYtNDMuNWg5OS44djQzLjV6IiBmaWxsPSIjMDAwMDAwIi8+CiAgPC9nPgo8L3N2Zz4K) +} +#container-3 { + background-repeat: no-repeat; + background-size: 80px; + transition: background-image 0.3s ease-in-out; + -webkit-transition: background-image 0.3s ease-in-out; + background-position: 50% 65%; + background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPHBhdGggZD0ibTk2LjYsMjYuOGgtODYuMWMtMi4yLDAtNC4xLDEuOC00LjEsNC4xdjY3LjJjMCwyLjIgMS44LDQuMSA0LjEsNC4xaDg2LjFjMi4yLDAgNC4xLTEuOCA0LjEtNC4xdi0xOS40bDE0LjksMTQuOWMwLjgsMC44IDEuOCwxLjIgMi45LDEuMiAwLjUsMCAxLjEtMC4xIDEuNi0wLjMgMS41LTAuNiAyLjUtMi4xIDIuNS0zLjh2LTUyLjVjMC0xLjYtMS0zLjEtMi41LTMuOC0xLjUtMC42LTMuMy0wLjMtNC40LDAuOWwtMTQuOSwxNC45di0xOS4zYy0wLjEtMi4zLTEuOS00LjEtNC4yLTQuMXptLTQuMSwzMy4zdjguOCAyNS4yaC03OHYtNTkuMmg3OHYyNS4yem0yMS45LTEydjMyLjlsLTEzLjctMTMuN3YtNS40bDEzLjctMTMuOHoiIGZpbGw9IiMwMDAwMDAiLz4KICA8L2c+Cjwvc3ZnPgo=) +} +#container-4 { + background-repeat: no-repeat; + background-size: 80px; + background-position: 50% 65%; + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgNDkwLjI4MiA0OTAuMjgyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0OTAuMjgyIDQ5MC4yODI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik0wLjA0MywyNDUuMTk3YzAuNiwxMC4xLDcuMywxOC42LDE3LDIxLjVsMTc5LjYsNTQuM2w2LjYsMTIzLjhjMC4zLDQuOSwzLjYsOS4yLDguMywxMC44YzEuMywwLjUsMi43LDAuNyw0LDAuNw0KCQljMy41LDAsNi44LTEuNCw5LjItNC4xbDYzLjUtNzAuM2w5MCw2Mi4zYzQsMi44LDguNyw0LjMsMTMuNiw0LjNjMTEuMywwLDIxLjEtOCwyMy41LTE5LjJsNzQuNy0zODAuN2MwLjktNC40LTAuOC05LTQuMi0xMS44DQoJCWMtMy41LTIuOS04LjItMy42LTEyLjQtMS45bC00NTksMTg2LjhDNS4xNDMsMjI1Ljg5Ny0wLjU1NywyMzUuMDk3LDAuMDQzLDI0NS4xOTd6IE0yMjYuMDQzLDQxNC4wOTdsLTQuMS03OC4xbDQ2LDMxLjgNCgkJTDIyNi4wNDMsNDE0LjA5N3ogTTM5MS40NDMsNDIzLjU5N2wtMTYzLjgtMTEzLjRsMjI5LjctMjIyLjJMMzkxLjQ0Myw0MjMuNTk3eiBNNDMyLjE0Myw3OC4xOTdsLTIyNy4xLDIxOS43bC0xNzkuNC01NC4yDQoJCUw0MzIuMTQzLDc4LjE5N3oiLz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjwvc3ZnPg0K) +} +#container-5 { + background-repeat: no-repeat; + background-size: 80px; + background-position: 50% 65%; + background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPgogIDxnPgogICAgPGc+CiAgICAgIDxwYXRoIGQ9Im0xOC43LDEyMi41aDkxLjZjMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi0xMDcuOWMwLTIuMy0xLjgtNC4xLTQuMS00LjFoLTY4LjdjLTAuMywwLTAuNywwLTEsMC4xLTAuMSwwLTAuMiwwLjEtMC4yLDAuMS0wLjMsMC4xLTAuNSwwLjItMC44LDAuMy0wLjEsMC4xLTAuMiwwLjEtMC4zLDAuMi0wLjMsMC4yLTAuNiwwLjQtMC44LDAuN2wtMjIuOSwyN2MtMC4zLDAuMy0wLjUsMC43LTAuNywxLjEtMC4xLDAuMS0wLjEsMC4zLTAuMSwwLjQtMC4xLDAuMy0wLjEsMC42LTAuMiwwLjkgMCwwLjEgMCwwLjEgMCwwLjJ2ODAuOWMtMS4wNjU4MWUtMTQsMi40IDEuOSw0LjIgNC4xLDQuMnptMTguOC0xMDAuOHYxMS44aC0xMGwxMC0xMS44em0tMTQuNywxOS45aDE4LjhjMi4zLDAgNC4xLTEuOCA0LjEtNC4xdi0yMi45aDYwLjV2OTkuN2gtODMuNHYtNzIuN3oiIGZpbGw9IiMwMDAwMDAiLz4KICAgICAgPHBhdGggZD0ibTk0LDUwLjVoLTU5Yy0yLjMsMC00LjEsMS44LTQuMSw0LjEgMCwyLjMgMS44LDQuMSA0LjEsNC4xaDU5YzIuMywwIDQuMS0xLjggNC4xLTQuMSAwLTIuMy0xLjgtNC4xLTQuMS00LjF6IiBmaWxsPSIjMDAwMDAwIi8+CiAgICAgIDxwYXRoIGQ9Im05NCw3MC4zaC01OWMtMi4zLDAtNC4xLDEuOC00LjEsNC4xIDAsMi4zIDEuOCw0LjEgNC4xLDQuMWg1OWMyLjMsMCA0LjEtMS44IDQuMS00LjEgMC0yLjItMS44LTQuMS00LjEtNC4xeiIgZmlsbD0iIzAwMDAwMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==) +} + +#container-6 { + +} + +#container-7 { + +} +.container-inner { + display: none; + background-color: rgb(221, 221, 221); + max-height: 100%; + min-height: 90%; +} +#add_screen { + padding-bottom: 20px; +} +.float { + opacity: 0.8; + min-width: 45px; + height: 45px; + background-color: #6666; + color: #FFF; + border-radius: 38px; + text-align: center; + margin: 5px; + pointer-events: auto; + outline:none; +} +.float2 { + opacity: 0.8; + width: 45px; + height: 45px; + background-color: #8888; + color: #FFF; + border-radius: 38px; + text-align: center; + z-index: 10; + margin: 5px; + pointer-events: auto; + outline:none; +} + +.rotate225 { + transform: rotate(135deg); + position: relative; + top: 1px; +} +.myVideo { + box-shadow: rgb(88, 88, 88) 0px 0px 5px 1px; + max-width: 800px !important; + max-height: 100% !important; + height: auto !important; + display: block !important; + margin: auto auto !important; + position: relative !important; + top: 50% !important; +} +#calendarButton { + cursor: pointer; + z-index: 6; + display:none; +} +#translateButton { + cursor: pointer; + z-index: 6; +} +#helpButton { + cursor: pointer; + z-index: 6; +} + +.popup .menu { margin: 2px; } + +.my-float { + margin-top: 7px; + opacity: 0.9; +} +.toggleSize { + font-size: 32px; + color: white; +} + +img { + max-width: 100%; +} +.in-animation { + animation: inlightbox 0.5s forwards; + position: fixed !important; + margin: 0 !important; +} + +.skip-animation { + position: fixed !important; + margin: 0 !important; + height: 100%; + width: 100%; + top: 0; + left: 0; +} +.skip-animation .container-inner{ + display:block; +} + +.out-animation { + animation: outlightbox 0.5s forwards; +} + +.pointer { + cursor: pointer; +} +@keyframes inlightbox { + 50% { + width: 100%; + left: 0; + height: 200px; + } + + 100% { + height: 100%; + width: 100%; + top: 0; + left: 0; + } +} +.column_neon { + color: white; + animation: neonGlow 2s infinite alternate cubic-bezier(0.455, 0.03, 0.515, 0.955); + box-shadow: 0 0 5px rgba(255, 255, 255, .8), 0 0 10px rgba(255, 255, 255, .8), 0 0 20px rgba(66, 220, 219, .5), 0 0 22px rgba(66, 220, 219, .5) +} +@keyframes neonGlow { + 100% { + box-shadow: 0 0 5px rgba(255, 255, 255, .8), 0 0 10px rgba(255, 255, 255, .8), 0 0 20px rgba(66, 220, 219, .5), 0 0 22px rgba(66, 220, 219, .5) + } + + 0% { + box-shadow: 0 0 2px rgba(255, 255, 255, .8), 0 0 3px rgba(255, 255, 255, .8), 0 0 4px rgba(66, 220, 219, .5) + } +} +.modal { + display: none; + position: fixed; + padding-top: 50px; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgb(0, 0, 0); + background-color: rgba(0, 0, 0, 0.5); +} +.modal-content { + position: relative; + background-color: white; + padding: 20px; + margin: auto; + max-width: 400px; +} +.close-btn { + float: right; + color: lightgray; + font-size: 24px; + font-weight: bold; +} +.close-btn:hover { + color: darkgray; +} +#chattoggle{ + top: 0.5px; + position: relative; +} + +.la-phone { + color: red; + top:0.5; +} + +.ondeck { + border: grey solid 2px !important; +} + +.recording{ + border: red solid 2px !important; +} + +.onair { + display: block !important; +} + +.raisedHand{ + background-color: #DD1A !important; +} + +@-webkit-keyframes animatetop { + from { + top: -300px; + opacity: 0 + } + + to { + top: 0; + opacity: 1 + } +} +@keyframes animatetop { + from { + top: -300px; + opacity: 0 + } + + to { + top: 0; + opacity: 1 + } +} +#request_info_prompt{ + z-index: 20; + color: white; + font-size: 30px; + font-size: 3.5vw; + top: 0; + align-self: center; + margin: 25vh 0; + position: absolute; +} + +.holder { + position: relative; + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + margin: auto; + object-fit: contain; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; +} + +.fadein { + animation: fadeIn var(--fadein-speed); + -webkit-animation: fadeIn var(--fadein-speed); + -moz-animation: fadeIn var(--fadein-speed); + -o-animation: fadeIn var(--fadein-speed); + -ms-animation: fadeIn var(--fadein-speed); +} + + + +@keyframes fadeIn { + 0% {opacity:0;} + 100% {opacity:1;} +} + +@-moz-keyframes fadeIn { + 0% {opacity:0;} + 100% {opacity:1;} +} + +@-webkit-keyframes fadeIn { + 0% {opacity:0;} + 100% {opacity:1;} +} + +@-o-keyframes fadeIn { + 0% {opacity:0;} + 100% {opacity:1;} +} + +@-ms-keyframes fadeIn { + 0% {opacity:0;} + 100% {opacity:1;} +} + +video { + transition: opacity .25s ease-in-out; + -moz-transition: opacity .25s ease-in-out; + -webkit-transition: opacity .25s ease-in-out; + pointer-events: auto; + background-color: transparent !important; + border: 0; + margin: 0; + user-select:none; + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ + -webkit-tap-highlight-color:transparent; + outline-style:none; + background-size: auto 50px; + background-repeat: no-repeat; + background-position: center; + background-image: url("data:image/svg+xml,%3Csvg viewBox='-42 0 512 512.002' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m210.351562 246.632812c33.882813 0 63.222657-12.152343 87.195313-36.128906 23.972656-23.972656 36.125-53.304687 36.125-87.191406 0-33.875-12.152344-63.210938-36.128906-87.191406-23.976563-23.96875-53.3125-36.121094-87.191407-36.121094-33.886718 0-63.21875 12.152344-87.191406 36.125s-36.128906 53.308594-36.128906 87.1875c0 33.886719 12.15625 63.222656 36.132812 87.195312 23.976563 23.96875 53.3125 36.125 87.1875 36.125zm0 0'/%3E%3Cpath d='m426.128906 393.703125c-.691406-9.976563-2.089844-20.859375-4.148437-32.351563-2.078125-11.578124-4.753907-22.523437-7.957031-32.527343-3.308594-10.339844-7.808594-20.550781-13.371094-30.335938-5.773438-10.15625-12.554688-19-20.164063-26.277343-7.957031-7.613282-17.699219-13.734376-28.964843-18.199219-11.226563-4.441407-23.667969-6.691407-36.976563-6.691407-5.226563 0-10.28125 2.144532-20.042969 8.5-6.007812 3.917969-13.035156 8.449219-20.878906 13.460938-6.707031 4.273438-15.792969 8.277344-27.015625 11.902344-10.949219 3.542968-22.066406 5.339844-33.039063 5.339844-10.972656 0-22.085937-1.796876-33.046874-5.339844-11.210938-3.621094-20.296876-7.625-26.996094-11.898438-7.769532-4.964844-14.800782-9.496094-20.898438-13.46875-9.75-6.355468-14.808594-8.5-20.035156-8.5-13.3125 0-25.75 2.253906-36.972656 6.699219-11.257813 4.457031-21.003906 10.578125-28.96875 18.199219-7.605469 7.28125-14.390625 16.121094-20.15625 26.273437-5.558594 9.785157-10.058594 19.992188-13.371094 30.339844-3.199219 10.003906-5.875 20.945313-7.953125 32.523437-2.058594 11.476563-3.457031 22.363282-4.148437 32.363282-.679688 9.796875-1.023438 19.964844-1.023438 30.234375 0 26.726562 8.496094 48.363281 25.25 64.320312 16.546875 15.746094 38.441406 23.734375 65.066406 23.734375h246.53125c26.625 0 48.511719-7.984375 65.0625-23.734375 16.757813-15.945312 25.253906-37.585937 25.253906-64.324219-.003906-10.316406-.351562-20.492187-1.035156-30.242187zm0 0'/%3E%3C/svg%3E"); +} + +.nogb { background-image: unset !important } + +video::-webkit-media-controls-timeline { + display: none; +} + +video::-webkit-media-controls-timeline-container { + display: none; +} + +audio::-webkit-media-controls-overlay-play-button, video::-webkit-media-controls-overlay-play-button { + display: none; +} + +audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button { + display: none; +} + +video::-webkit-media-controls-toggle-closed-captions-button { + display: none; +} + +video.clean::-webkit-media-controls-current-time-display { + display: inherit; +} + +video.clean::-webkit-media-controls-time-remaining-display { + display: inherit; +} + +video.clean::-webkit-media-controls-timeline { + display: inherit; +} + +video.clean::-webkit-media-controls-timeline-container { + display: inherit; +} + +.mirrorControl::-webkit-media-controls-enclosure { + padding: 0px; + height: 30px; + transform: scaleX(-1); + -webkit-transform: scaleX(-1); +} +.popup-screen { + align-text: center; + position: absolute; + display:none; + top:0; + left:0; + z-index: 7 !important; + padding: 20px; + margin:15px 15px 80px 15px; + width: 80vh !important; + height: 80vh !important; + background-color: #ccc !important; + border: solid 1px #dfdfdf !important; + box-shadow: 1px 1px 2px #cfcfcf !important; +} +.context-menu { + display: none; + position: absolute; + z-index: 10 !important; + padding: 12px 0 !important; + width: 240px !important; + background-color: #fff !important; + border: solid 1px #dfdfdf !important; + box-shadow: 1px 1px 2px #cfcfcf !important; +} +.popup-message { + display: none; + align-text: center; + position: absolute; + z-index: 21 !important; + padding: 3px !important; + min-width: 180px !important; + background-color: #fff !important; + border: solid 1px #dfdfdf !important; + box-shadow: 1px 1px 2px #cfcfcf !important; +} +.context-menu--active { + display: block !important; +} +.context-menu__items { + list-style: none !important; + margin: 0; + padding: 0; +} +.context-menu__item { + display: block; + margin-bottom: 4px !important; +} +.context-menu__item:last-child { + margin-bottom: 0 !important; +} +.context-menu__link { + display: block; + padding: 4px 12px; + color: #0066aa !important; + text-decoration: none; +} +.context-menu__link:hover { + color: #fff !important; + background-color: #0066aa !important; +} +.audioTitle { + text-align: left; + padding: 7px 0px; +} +.audioTitle2 { + text-align: left; + padding: 0px 10px 10px 1px; +} +.multiselect .multiselect-trigger:hover { + cursor: pointer; + cursor: hand; + text-decoration: none; +} +.multiselect .multiselect-trigger.open { + border-bottom: 0; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} +.multiselect .multiselect-trigger.closed { + border-bottom: 1px solid #ccc; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} +#headphonesDiv3 { + text-align: left; + margin: 17px 0 0 0; + width: 450px; + background-color: #f3f3f3; + padding: 10px 10px; + border: 1px solid #ccc; + vertical-align: middle; +} +#headphonesDiv { + text-align: left; + margin: 17px 0; + width: 450px; + background-color: #f3f3f3; + padding: 10px 10px; + border: 1px solid #ccc; + vertical-align: middle; +} + +#effectSelector3{ + background-color: #FFF; + display: inline-block; + vertical-align: middle; + padding: 3px; + font-size: 93%; + max-width: 100%; + width: 90%; +} + +#effectsDiv3 { + text-align: left; + width: 450px; + background-color: #f3f3f3; + padding: 10px 10px; + border: 1px solid #ccc; + vertical-align: middle; + margin: 17px 0 0 0; +} +#videoSettings { + margin: auto auto; + background-color: #f3f3f3; + width: 450px; + padding: 10px 0; + margin: 0px 0 0px 0; + border: 1px solid #ccc; +} +#audioMenu { + margin: 15px 0 0 0; +} + +#videosource { + display: inline-block; + vertical-align: middle; + font-size: 100%; +} +#videoSourceSelect { + display: inline-block; + vertical-align: middle; + font-size: 100%; + max-width: 260px; +} +#effectSelector{ + display: inline-block; + vertical-align: middle; + font-size: 100%; + max-width: 260px; +} +.gone { + position: absolute; + display: inline-block; + left: -9999px; +} +.grabLinks { + display: inline-flex; + cursor: grab; + font-weight: bold; + font-size: 1em; + padding: 10px; + margin: 5px 0; + word-break: break-all; +} +.grabLinks a:hover { + color: black !important; +} +.grabLinks a:active { + color: black !important; +} +.grabLinks a:link { + color: black !important; +} + +.hidden { + display:none; + visibility: hidden; + width:0px; + height:0px; +} +/* visited link */ +.grabLinks a:visited { + color: black !important; +} +#videoSettings3 { + margin: 0 auto 15px auto; + background-color: #f3f3f3; + width: 450px; + padding: 7px 10px 1px 10px; + border: 1px solid #ccc; + font-size: 90%; +} +#videoSource3 { + background-color: #FFF; + display: inline-block; + vertical-align: middle; + padding: 3px; + font-size: 93%; + max-width: 370px; +} +#outputSource { + background-color: #FFF; + display: inline-block; + vertical-align: middle; + padding: 4px; + font-size: 93%; + max-width: 100%; +} +#outputSource3 { + background-color: #FFF; + display: inline-block; + vertical-align: middle; + padding: 3px; + font-size: 93%; + max-width: 100%; +} +.videoMenu { + background-color: #f3f3f3; + width: 450px; + display: inline-block; + padding: 10px 10px; + border: 1px solid #ccc; + vertical-align: middle; + text-align: left; +} + +div.multiselect { + width: 450px; + white-space: nowrap; + overflow: hidden; + margin: auto auto; + border: 1px solid #ccc; + border-bottom: 0; + display: inline-block; + padding: 4px 10px 10px 10px; + background-color: #f3f3f3; +} +.multiselect .multiselect-contents { + display: block; + margin: 0; + font-size: 80%; + padding: 3px 5px 1px; + border-top: 0; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + text-align: left; + background-color: white; +} +.multiselect .multiselect-contents li { + list-style: none; + font-size: 120%; + padding: 2px; + overflow: hidden; +} +.select .select-trigger:hover { + cursor: pointer; + cursor: hand; + text-decoration: none; +} +.select .select-trigger.open { + border-bottom: 0; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} +.select .select-trigger.closed { + border-bottom: 1px solid #ccc; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} +.select .select-contents { + display: none; + margin: 0; + padding: 0 24px 24px; + border: 1px solid #ccc; + border-top: 0; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} +.select .select-contents li { + list-style: none; +} +::-webkit-input-placeholder { + color: #555 !important; +} +::-moz-placeholder { + color: #555 !important; +} +:-ms-input-placeholder { + color: #555 !important; +} +:-moz-placeholder { + color: #555 !important; +} +label { + font-weight: normal; +} +input[type=checkbox] { + /* Double-sized Checkboxes */ + + -ms-transform: scale(1.4); + /* IE */ + + -moz-transform: scale(1.4); + /* FF */ + + -webkit-transform: scale(1.4); + /* Safari and Chrome */ + + -o-transform: scale(1.4); + /* Opera */ + + transform: scale(1.4); + padding: 5px; + margin: 0 5px 0 1px; +} +#screenshare { + height: 300px; + display: inline-block; + max-height: 50vh; + max-width: 50vh; + border: 0; + margin: 0; + padding: 0; + text-shadow: 0; + box-shadow: 0; + text-decoration: none; + border-image-width: 0; + background-size: contain; + background-color: rgba(0, 0, 0, 0); +} +.inMessage { + color: #000; + margin: 3px; + border-radius: 5px; + background: #FFF; + padding: 5px; + text-align: left; + margin: 10px 3px; +} +.outMessage { + color: #000; + margin: 3px; + border-radius: 5px; + background: #BCF; + padding: 5px; + text-align: right; + margin: 10px 3px; +} +#chatBody { + z-index: 12; + background-color: #0004; + width: 100%; + border-radius: 5px; + padding: 1px 7px; + overflow-y:scroll; + overflow-wrap: anywhere; + max-height: 800px; +} + +#chatBody::-webkit-scrollbar { + width: 0px; + background: transparent; /* make scrollbar transparent */ +} + +#chatModule { + bottom: 50px; + position: fixed; + margin: 10px; + align-self: center; + width: 400px; + max-width: 100%; +} +#chatInput { + color: #000; + background-color: #FFFE; + max-width: 700px; + min-width: 320px; + font-size: 105%; + margin-left: 7px; + padding: 3px; + border: 3px solid black; +} +.debugStats { + font-size: 0.8rem; + list-style-type: none; + left: 50px; + top: 0px; + width: 300px; + min-height: 200px; + max-height: 99vh; + overflow-y: auto; + background-color: rgba(0, 0, 0, 0.95); + position: absolute; + z-index: 20; + color: white; + padding: 20px; + border: 2px solid #1d1d1d; +} +.debugStats::-webkit-scrollbar { + width: 0.5em; +} +.debugStats::-webkit-scrollbar-track { + background: black; + border-radius: 10px; +} + +/* Handle */ +.debugStats::-webkit-scrollbar-thumb { + background: rgb(119, 119, 119); + border-radius: 10px; +} + +/* Handle on hover */ +.debugStats::-webkit-scrollbar-thumb:hover { + background: rgb(158, 158, 158); + ; +} +.debugStats h1 { + font-size: 1rem; + text-align: left; + text-transform: uppercase; + margin-bottom: 10px; + margin-top: -5px; +} +.debugStats h2 { + font-size: 0.8rem; + text-align: left; + text-transform: uppercase; + margin-top: 10px; + white-space: nowrap; + text-overflow: ellipsis; + display: block; + overflow: hidden; +} +.viewstats::-webkit-scrollbar-track { + box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); +} +.debugStats li { + display: flex; + margin: 5px 0px; +} +.debugStats li:nth-child(even) { + background: rgba(33, 33, 33, 0.8); + padding: 2px 0px; +} +.debugStats li span:first-child { + flex: 1; +} +.debugStats li span:last-child { + flex: 1; + text-align: right; +} +.debugStats .close { + font-weight: bold; + color: white; + display: block; + background: none; + padding: 0; + margin: 0; + font-size: 1.5rem; + border: none; + top: 10px; + right: 10px; +} +.debugStats button:not(.close) { + margin: 10px 0px; + padding: 10px 0px; + background: #263250; + color: white; + border-radius: 0; + width: 100%; + font-weight: bold; + border-bottom: 2px solid #364c84; +} +@media only screen and (max-width: 390px) { + #chatBody { + z-index: 12; + background-color: #FFF1; + width: 100%; + border-radius: 5px; + padding: 1px 7px; + margin: 0px; + } + + #chatModule { + bottom: 50px; + position: fixed; + margin: 0px; + align-self: center; + width: 400px; + max-width: 100%; + } + + #chatInput { + max-width: 99%; + min-width: 240px; + margin-left: 11px; + font-size: 100%; + } +} +.directorMargins { + margin: var(--director-margin); +} +.hideLinksClass { + background-color: var(--container-color); + width:1191px; + padding: 10px; + margin: 10px; +} +.directorContainer { + background-color: var(--container-color); + display: grid; + grid-template-columns: 1fr ; + margin: 10px 0px 10px 10px; + padding: 10px; + max-width: 1191px +} +@media only screen and (max-width: 390px) { + +} + +#directorLinksButton{ + cursor:pointer; +} +.directorContainer.half { + background-color: var(--container-color); + display: grid; + grid-template-columns: 1fr 1fr; + padding: 10px 10px; + width: 591px; +} +.directorBlock { + padding: 10px 10px 5px 10px; + margin: var(--regular-margin); + color: white; + position:relative; + max-width: 100%; + overflow: hidden; +} +.directorBlock:nth-child(1) { + background-color: var(--blue-accent); +} +.directorBlock:nth-child(2) { + background-color: var(--green-accent); +} +.directorBlock:nth-child(3) { + background-color: var(--olive-accent); +} +.directorBlock:nth-child(4) { + background-color: var(--red-accent); +} +.directorBlock button { + bottom: 0; + margin: 10px; +} +.directorBlock button i { + margin-right: 5px; +} +.task { + color: #808080; + width: 100%; + margin-top: 10px; +} +.directorBlock h2 { + text-transform: uppercase; + margin-bottom: 10px; + margin-left: 5px; + font-size:1.2em; +} +#toggleroomnotes { + grid-column: 4; + grid-row: 1; +} +div#roomnotes2 { + background: var(--container-color); + padding: 10px !important; + margin: 0 var(--regular-margin) 10px var(--regular-margin); + width: 100%; +} +.directorsgrid .directorContainer:nth-child(2) button { + grid-row: 1; + grid-column: 4; +} +.directorsgrid .directorContainer:nth-child(2) span { + grid-row: 1; + grid-column: 1; +} +.directorsgrid button { + text-transform: lowercase; +} +.controlsGrid { + grid-template-columns: 1fr 1fr; + display: grid; +} +.controlsGrid button { + margin: 5px; + text-align: right; +} +.controlsGrid span button { + margin-right: 0; + padding-left: 3px; + text-align: right; +} +.controlsGrid input { + margin: 5px var(--regular-margin); +} + +.pull-right { + float: right; + right: 0; +} +.pull-left { + float: left; + left: 0; +} +i.las.la-circle { + color: red; +} +.streamID { + text-align: right; + margin: 5px; + font-size: 0.7em; + text-overflow: ellipsis; + overflow: hidden; +} +.streamID i { + margin-left: 5px; + font-size: 1.3em; + position: relative; + top: 2px; +} +.soloLink { + background: none; + border-radius: 0; + width: 100%; + cursor: grab; + white-space: nowrap; + text-overflow: ellipsis; + font-size: 1.2em; + font-weight: 700; +} +.vidcon>h2 { + font-size: 1em; + margin-top: 20px; +} +div#guestFeeds { + background: var(--container-color); + padding: 5px 0 15px 20px; + display: inline-block; + margin: 0px var(--regular-margin); +} + +div#guestFeeds:empty { + display:none; +} + +#press2talk[data-enabled="true"] { + background: #1e0000; + -webkit-box-shadow: inset 0px 0px 1px #b90000; + -moz-box-shadow: inset 0px 0px 1px #b90000; + box-shadow: inset 0px 0px 1px #b90000; + outline: none; +} + +/* Top of the page share link */ +a#reshare { + white-space: nowrap; + margin: 0; + padding: 0; + display: inline; +} +#copythisurl+i { + display: inline; + font-size: 130%; +} + +/* Top of the page Join room input*/ +#joinroomID { + border-radius: 0; + padding: 5px; +} +#joinroomID+button { + margin: 0px var(--regular-margin); +} + +/* Tips for guests */ +span#guestTips { + margin: 0 auto 15px auto; + width: 450px; + display: flex; + flex-direction: column; + text-align: left; + background: #f3f3f3; + border: 1px solid #cccccc; + padding: 10px; +} + +#guestTips p { + font-weight: bold; + margin-bottom: 10px; +} + +#guestTips span:nth-child(1) { + color: red; +} + +#guestTips > span > i { + font-size: 2.5em; + margin-right: 10px; +} + +#guestTips > span > span { + line-height: 2.5em; + vertical-align: bottom; +} + +.video-label { + position: absolute; + bottom: 0.6vh; + left: 0.5vh; + margin: 0px; + color: white; + padding: 5px 10px; + background: rgba(0, 0, 0, .5); + font-size: 1em; + pointer-events:none; +} + + +.video-label.zoom { + bottom: 0; + left: 0; + pointer-events:none; +} + +.video-label.teams { + background: rgba(0, 0, 0, .4); + pointer-events:none; + border-radius: 5px; +} + +.video-label.skype { + bottom: 2vh; + left: 50%; + transform: translateX(-50%); + background: rgba(0, 0, 0, .8); + pointer-events:none; + border-radius: 5px; + font-size: 0.8em; +} + +.video-label.ninjablue { + bottom: 5%; + left: 0; + background: #141926; + padding: 10px 5%; +} + +.video-label.toprounded { + top: 0; + bottom: unset; + background: rgb(0 0 0 / 70%); + padding: 10px 5%; + left: 50%; + transform: translateX(-50%); + width: 50%; + text-align: center; + border-bottom-left-radius: 50px; + border-bottom-right-radius: 50px; + text-transform: uppercase; + letter-spacing: 3; + box-shadow: 0px 0px 10px #00000059; + font-size: 0.7em +} + +.video-label.fire { + text-shadow: 0 -1px 4px #FFF, 0 -2px 10px #ff0, 0 -10px 20px #ff8000, 0 -18px 40px #F00; + font-weight: bold; + bottom: 2vh; + left: 0; + width: 100%; + text-align: center; +} + +.video-meter { + padding:0.5vh; + display:block; + width:0.5vh; + height:0.5vh; + min-width:10px; + min-height:10px; + top: 2vh; + right: 2vh; + background-color:green; + position:absolute; + border-radius: 2vh; + pointer-events:none; + border: 1px black solid; +} +.video-meter-director { + width: 10px; + height: 10px; + top: 8px; + right: 10px; +} +.video-meter2 { + padding:0; + width: 4px; + height:0%; + min-width:2px; + bottom: 1px; + right: 5px; + background-color:#0000; + position:absolute; + border-radius: 2vh; + pointer-events:none; + border: 1px black solid; + transition: height 0.1s ease, background-color 0.1s ease; +} + +#voiceMeterTemplate{ + display:none; +} +#voiceMeterTemplate2{ + display:none; +} + +#userList{ + line-height: 1.3em; +} + +#userList > div > .video-meter { + padding: 5px; + margin-left: 5px; + top: 0; + right: 0; + position: relative; + display: inline-block; +} + +.video-mute-state { + top: 2vh; + right: 2vh; + position: absolute; + color:white; + border-radius: 2vh; + background-color:#b11313; + padding: 2px 2px 2px 1px; +} + +.video-mute-state-userlist { + display:inline-block; + color:white; + border-radius: 2vh; + background-color:#b11313; + padding: 2.2px 1.5px 2px 2px; + margin: 0 0 0 5px; +} + + +#help_directors_room{ + cursor:pointer; +} + +.iframeblob{ + padding-top:18px; + text-align: left; + width: 600px; + display: block; + margin: auto; +} +#shareScreenGear{ + display:none; +} + +div.message-card { + padding: 10px; + display: block; + padding-left: 1em; + align-items: center; + width: 600px; + margin: 0 auto; + position: relative; + padding-left: 60px; + margin: 0 auto; + margin-bottom: 20px; + box-shadow: 0px 5px 10px -5px #a9a9a9; +} + +div.message-card a { + color: rgb(0 77 218); + font-weight: bold; + text-decoration: underline; +} + +.warning.message-card { + border-left: 4px solid #eff150; + background: #fffded; +} +.info.message-card { + border-left: 4px solid #aacefd; + background: #e6e8f0; +} + +.message-card h1 { + display: block; + font-size: 110%; + text-align: left; +} + +.message-card p { + display: block; + text-align: left; + margin-top: 10px; +} + +div.message-card:before { + font-family: 'Line Awesome Free'; + font-weight: 900; + font-size: 2em; + margin-right: 0.5em; + position: absolute; + top: 6px; + left: 10px; +} + +div.message-card.warning:before { + content: "\f071"; +} + +div.message-card.info:before { + content: "\f05a"; +} + +@keyframes floating { + 0% { transform: translate(0, 0px); } + 50% { transform: translate(0, 15%); } + 100% { transform: translate(0, -0px); } +} + +.video-label.floating3d { + text-transform: uppercase; + display: block; + color: #FFFFFF; + text-shadow: 0 1px 0 #CCCCCC, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 10px 10px rgba(0,0,0,.2), 0 20px 20px rgba(0,0,0,.15); + color: #FFFFFF; + animation-name: floating; + animation-duration: 5s; + animation-iteration-count: infinite; + animation-timing-function: ease-in-out; + width: 100%; + font-size: 5em; + font-weight:bold; + text-align: center; + bottom: 4vh; + position: absolute; +} + +.director-link-icons { + font-size: 1.5em; + float: left; + bottom: 4px; + position: relative; + margin-right: 9px; +} + +.switch { + position: relative; + margin:5px 5px 2px 5px; + width: 40px; + height: 24px; + bottom:20px; + border-radius: 2px; + display: inline-block; +} + +.switch input { + width: 0; + height: 0; + opacity: 0; +} + +.slider { + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + -webkit-transition: .3s; + transition: .3s; + position: absolute; +} + +.slider:before { + content: ""; + height: 17px; + width: 17px; + left: 3px; + bottom: 3px; + background-color: white; + -webkit-transition: .3s; + transition: .3s; + position: absolute; +} + +input:checked + .slider { + background-color: #86b98f; +} + +input:focus + .slider { + box-shadow: 0 0 1px #86b98f; +} + +input:checked + .slider:before { + -webkit-transform: translateX(16px); + -ms-transform: translateX(16px); + transform: translateX(16px); +} + + +#promptModal, #roomSettings { + position: absolute; + background-color: rgb(221 221 221); + box-shadow: 0 0 30px 10px #0000005c; + color: black; + font-size: 1.2em; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + border-radius: 10px; + font-weight: bold; + z-index:31; + min-width:400px; + max-width:90%; + overflow-wrap: break-word; +} + +.largeTextEntry { + width:300px; + margin: 0 0 0 55px; + font-size: 1em; + padding: 0.4em; + display: block; + +} +.promptModalInner { + position: relative; + padding: 1em; +} + +#iframe_source{ + width: 100%; + height: 100%; + margin: auto; + border: 10px dashed rgb(64 65 62) +} + +#SafariWarning{ + display:none; + width: 450px; + border-left: 4px solid #eff150; + background: #fffded; + padding: 10px; + align-items: center; + position: relative; + margin: 17px auto 20px auto; + box-shadow: 0px 5px 10px -5px #a9a9a9; + text-align: left; +} +#SafariWarning > p { + text-align: left; + display:inline-block; + padding-left: 38px; + +} +#SafariWarning > i { + position: absolute; + font-size: 2em; + padding: 2px 0 0 0; +} + +#alertModal { + position: absolute; + background-color: rgb(221 221 221); + box-shadow: 0 0 30px 10px #0000005c; + color: black; + font-size: 1.2em; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + border-radius: 10px; + font-weight: bold; + z-index:32; + min-width:360px; + max-width:90%; + overflow-wrap: break-word; +} + +#connectUsers{ + float: right; + display: none; + position: absolute; + max-width: 400px; + min-width: 150px; + max-height: 80%; + background-color: #08090e; + z-index: 5; + padding: 10px; + right: 20px; + bottom: 120px; + box-shadow: 2px 2px #313131; + border-radius: 5px; + border: 1px solid #252525; + opacity: 0.7; + color: white; +} + +#alertModal a:link { + color: blue; +} + +/* visited link */ +#alertModal a:visited { + color: blue; +} + +/* mouse over link */ +#alertModal a:hover { + color: blue; +} + +/* selected link */ + #alertModal a:active { + color: blue; +} + +.alertModalInner { + position: relative; + padding: 2em; +} + +.modalClose { + position: absolute; + top: -4px; + right: 4px; + cursor: pointer; + font-weight: bolder; + font-size: 1.8em; +} + +#modalBackdrop { + background: var(--background-color); + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 0; + opacity: 0.8; +} + +@media only screen and (max-width: 390px) { + .alertModal { + width: 90%; + } +} + +.desktop-capturer-selection { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + background: rgba(30,30,30,.75); + color: #fff; + z-index: 10000000; + display: flex; + align-items: center; + justify-content: center; +} +.desktop-capturer-selection__scroller { + width: 100%; + max-height: 100vh; + overflow-y: auto; +} +.desktop-capturer-selection__list { + max-width: calc(100% - 100px); + margin: 50px; + padding: 0; + display: flex; + flex-wrap: wrap; + list-style: none; + overflow: hidden; + justify-content: center; +} +.desktop-capturer-selection__item { + display: flex; + margin: 4px; +} +.desktop-capturer-selection__btn { + display: flex; + flex-direction: column; + align-items: stretch; + width: 145px; + margin: 0; + border: 0; + border-radius: 3px; + padding: 4px; + background: #252626; + text-align: left; + transition: background-color .15s, box-shadow .15s; +} +.desktop-capturer-selection__btn:hover, +.desktop-capturer-selection__btn:focus { + background: rgba(98,100,167,.8); +} +.desktop-capturer-selection__thumbnail { + width: 100%; + height: 81px; + object-fit: cover; +} +.desktop-capturer-selection__name { + margin: 6px 0 6px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; } \ No newline at end of file diff --git a/main.js b/main.js index 2813197..4907de5 100644 --- a/main.js +++ b/main.js @@ -1,17770 +1,17773 @@ -/* -* Copyright (c) 2020 Steve Seguin. All Rights Reserved. -* -* Use of this source code is governed by the APGLv3 open-source license -* that can be found in the LICENSE file in the root of the source -* tree. Alternative licencing options can be made available on request. -* -*/ -/*jshint esversion: 6 */ - -var formSubmitting = true; -var activatedPreview = false; - - -// function log(msg){ // uncomment to enable logging. - // console.log(msg); -// } -// function warnlog(msg, url=false, lineNumber=false){ - // onsole.warn(msg); - // if (lineNumber){ - // console.warn(lineNumber); - // } -// } -// function errorlog(msg, url=false, lineNumber=false){ - // console.error(msg); - // if (lineNumber){ - // console.error(lineNumber); - // } -// } - -function addEventToAll(targets, trigger, callback) { // js helper - const target = document.querySelectorAll(targets); - var triggers = trigger.split(" "); - for (let i = 0; i < target.length; i++) { - for (let j = 0; j < triggers.length; j++) { - setTimeout(function(t1,t2){ - t1.addEventListener(t2, function(e) { - callback(e, t1); - }); - },0,target[i],triggers[j]); - } - } -} - -function mapToAll(targets, callback, parentElement = document) { // js helper - if (!targets) { - return; - } - if (!parentElement) { - return; - } - const target = parentElement.querySelectorAll(targets); - for (let i = 0; i < target.length; i++) { - callback(target[i]); - } -} - -var isIFrame = false; -if ( parent && (window.location !== window.parent.location )) { - isIFrame = true; -} - -function changeParam(url, paramName, paramValue) { - paramName = paramName.replace("?", ""); - var qind = url.indexOf('?'); - url = url.replace("?", "&"); - var params = url.substring(qind + 1).split('&'); - var query = ''; - var match = false; - for (var i = 0; i < params.length; i++) { - var tokens = params[i].split('='); - var name = tokens[0]; - var value = ""; - if (tokens.length > 1 && tokens[1] !== '') { - value = tokens[1]; - } - - if (name == paramName) { - if (match) { - continue; - } // already matched the first time. - match = true; - value = paramValue; - } - if (value !== "") { - value = '=' + value; - } - - if (query == '') { - query = "?" + name + value; - } else { - query = query + '&' + name + value; - } - } - return url.substring(0, qind) + query; -} - -function updateURL(param, force = false, cleanUrl = false) { - param = param.replace("?", ""); - var para = param.split('='); - if (cleanUrl) { - if (history.pushState) { - var href = new URL(cleanUrl); - if (para.length == 1) { - href = changeParam(cleanUrl, para[0], ""); - } else { - href = changeParam(cleanUrl, para[0], para[1]); - } - log("--" + href.toString()); - window.history.pushState({path: href.toString()}, '', href.toString()); - } - } else if (!(urlParams.has(para[0]))) { // don't need to replace as it doesn't exist. - if (history.pushState) { - var href = window.location.href; - href = href.replace("??", "?"); - var arr = href.split('?'); - var newurl; - if (arr.length > 1 && arr[1] !== '') { - newurl = href + '&' + param; - } else { - newurl = href + '?' + param; - } - - window.history.pushState({path: newurl.toString()}, '', newurl.toString()); - } - } else if (force) { - if (history.pushState) { - var href = new URL(window.location.href); - if (para.length == 1) { - href = changeParam(window.location.href, para[0], ""); - } else { - href = changeParam(window.location.href, para[0], para[1]); - } - log("---" + href.toString()); - window.history.pushState({path: href.toString()}, '', href.toString()); - } - } - if (session.sticky) { - setStorage("settings", encodeURI(window.location.href), 90); - } - urlParams = new URLSearchParams(window.location.search); -} - -function changeGuestSettings(ele){ - var eles = ele.querySelectorAll('[data-param]'); - var UUID = ele.dataset.UUID; - var settings = {}; - for (var i = 0;i< eles.length; i++){ - if (eles[i].tagName.toLowerCase() == "input"){ - if (eles[i].checked===true){ - settings[eles[i].dataset.param] = true; - } else if (eles[i].checked===false){ - settings[eles[i].dataset.param] = false; - } else { - settings[eles[i].dataset.param] = eles[i].value; - } - } - } - warnlog(settings); - - if (!settings.changepassword){ - delete settings.password; - } - - delete settings.changepassword; - - if (!settings.changeroom){ - // send Migration message - delete settings.roomid; - } - delete settings.roomid; - delete settings.changeroom; - - warnlog(UUID); - var msg = {}; - msg.changeParams = settings; - session.sendRequest(msg, UUID); - closeModal(); -} - -// proper room migration needs to happen; in sync. -// updateMixer after settings changed -// password needs to be special cased -// room shouldn't be sent - -function applyNewParams(changeParams){ - for (var key in changeParams){ - session[key] = changeParams[key]; - log(key); - } - log(changeParams); - updateMixer(); -} - -function promptUser(eleId, UUID=null){ - if (document.getElementById("modalBackdrop")){ - getById("promptModal").innerHTML = ''; // Delete modal - getById("promptModal").remove(); - getById("modalBackdrop").innerHTML = ''; // Delete modal - getById("modalBackdrop").remove(); - } - - zindex = 30 + document.querySelectorAll('#promptModal').length; - modalTemplate = - `
    -
    - × - -
    -
    -
    `; - document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end - - getById("promptModalMessage").innerHTML = getById(eleId).innerHTML; - if (UUID){ - getById("promptModalMessage").dataset.UUID = UUID; - } - - - document.getElementById("modalBackdrop").addEventListener("click", closeModal); - - getById("promptModal").addEventListener("click", function(e) { - e.stopPropagation(); - return false; - }); - -} -var warnUserTimeout=null; -function warnUser(message, timeout=false){ - // Allows for multiple alerts to stack better. - // Every modal and backdrop has an increasing z-index - // to block the previous modal - if (document.getElementById("modalBackdrop")){ - getById("alertModal").innerHTML = ''; // Delete modal - getById("alertModal").remove(); - getById("modalBackdrop").innerHTML = ''; // Delete modal - getById("modalBackdrop").remove(); - } - - zindex = 31 + document.querySelectorAll('.alertModal').length; - message = message.replace(/\n/g,"
    "); - modalTemplate = - `
    -
    - × - ${message} -
    -
    -
    `; - document.body.insertAdjacentHTML("beforeend", modalTemplate); // Insert modal at body end - - document.getElementById("modalBackdrop").addEventListener("click", closeModal); - - clearTimeout(warnUserTimeout); - if (timeout){ - warnUserTimeout = setTimeout(closeModal, timeout); - } - getById("alertModal").addEventListener("click", function(e) { - e.stopPropagation(); - return false; - }); - -} -function closeModal(){ - getById("modalBackdrop").innerHTML = ''; // Delete modal - getById("modalBackdrop").remove(); - getById("alertModal").innerHTML = ''; // Delete modal - getById("alertModal").remove(); - getById("promptModal").innerHTML = ''; // Delete modal - getById("promptModal").remove(); -} - -var filename = false; -try { - filename = window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1); - filename = filename.replace("??", "?"); - filename2 = filename.split("?")[0]; - // split at ??? - if (filename.split(".").length == 1) { - if (filename2.length < 2) { // easy win - filename = false; - } else if (filename.startsWith("&")) { // easy win - var tmpHref = window.location.href.substring(0, window.location.href.lastIndexOf('/')) + "/?" + filename.split("&").slice(1).join("&"); - log("TMP " + tmpHref); - updateURL(filename.split("&")[1], true, tmpHref); - filename = false; - } else if (filename2.split("&")[0].includes("=")) { - log("asdf " + filename.split("&")[0]); - if (history.pushState) { - var tmpHref = window.location.href.substring(0, window.location.href.lastIndexOf('/')); - tmpHref = tmpHref + "/?" + filename; - filename = false; - //warnUser("Please ensure your URL is correctly formatted."); - window.history.pushState({path: tmpHref.toString()}, '', tmpHref.toString()); - } - } else { - filename = filename2.split("&")[0]; - if (filename2 != filename) { - warnUser("Warning: Please ensure your URL is correctly formatted."); - } - } - } else { - filename = false; - } - log(filename); -} catch (e) { - errorlog(e); -} - - -(function(w) { - w.URLSearchParams = w.URLSearchParams || function(searchString) { - var self = this; - searchString = searchString.replace("??", "?"); - self.searchString = searchString; - self.get = function(name) { - var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString); - if (results == null) { - return null; - } else { - return decodeURI(results[1]) || 0; - } - }; - }; - -})(window); - -var urlEdited = window.location.search.replace(/\?\?/g, "?"); -urlEdited = urlEdited.replace(/\?/g, "&"); -urlEdited = urlEdited.replace(/\&/, "?"); - -if (urlEdited !== window.location.search){ - warnlog(window.location.search + " changed to " + urlEdited); - window.history.pushState({path: urlEdited.toString()}, '', urlEdited.toString()); -} -var urlParams = new URLSearchParams(urlEdited); - -var sanitizeStreamID = function(streamID) { - streamID = streamID.trim(); - - if (streamID.length < 1) { - streamID = session.generateStreamID(8); - if (!(session.cleanOutput)) { - warnUser("No streamID was provided; one will be generated randomily.\n\nStream ID: " + streamID); - } - } - var streamID_sanitized = streamID.replace(/[\W]+/g, "_"); - if (streamID !== streamID_sanitized) { - if (!(session.cleanOutput)) { - warnUser("Info: Only AlphaNumeric characters should be used for the stream ID.\n\nThe offending characters have been replaced by an underscore"); - } - } - if (streamID_sanitized.length > 44) { - streamID_sanitized = streamID_sanitized.substring(0, 44); - if (!(session.cleanOutput)) { - warnUser("The Stream ID should be less than 45 alPhaNuMeric characters long.\n\nWe will trim it to length."); - } - } - return streamID_sanitized; -}; - -var checkStrength = function(string) { - var matcher = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{7,30}$/; - if (string.match(matcher)) { - return true; - } else if (string.length > 20) { - return true; - } else { - return false; - } -}; - -var checkStrengthRoom = function() { - var result1 = checkStrength(getById('videoname1').value); - var result2 = getById('passwordRoom').value.length; - var target = getById('securityLevelRoom'); - target.style.display = "block"; - if (result1) { - if (result2) { - target.innerHTML = "Share only with those you trust"; - } else { - target.innerHTML = "A password is recommended"; - } - } else { - target.innerHTML = "Insecure room name. Allowed chars: A-Z, a-z, 0-9, _"; - } -}; - -var sanitizeChat = function(string) { - var temp = document.createElement('div'); - temp.innerText = string; - temp.innerText = temp.innerHTML; - temp = temp.textContent || temp.innerText || ""; - temp = temp.substring(0, Math.min(temp.length, 500)); - return temp.trim(); -}; - -var sanitizeString = function(str) { - str = str.replace(/[^a-z0-9áéíóúñü \.,_-]/gim, ""); - return str.trim(); -}; - -var sanitizeLabel = function(string) { - let temp = document.createElement("div"); - temp.innerText = string; - temp.innerText = temp.innerHTML; - temp = temp.textContent || temp.innerText || ""; - temp = temp.substring(0, Math.min(temp.length, 50)); - return temp.trim(); -}; - -var sanitizeRoomName = function(roomid) { - roomid = roomid.trim(); - if (roomid === "") { - return roomid; - } else if (roomid === false) { - return roomid; - } - - var sanitized = roomid.replace(/[\W]+/g, "_"); - if (sanitized !== roomid) { - if (!(session.cleanOutput)) { - warnUser("Info: Only AlphaNumeric characters should be used for the room name.\n\nThe offending characters have been replaced by an underscore"); - } - } - if (sanitized.length > 30) { - sanitized = sanitized.substring(0, 30); - if (!(session.cleanOutput)) { - warnUser("The Room name should be less than 31 alPhaNuMeric characters long.\n\nWe will trim it to length."); - } - } - return sanitized; -}; - -var sanitizePassword = function(passwrd) { - if (passwrd === "") { - return passwrd; - } else if (passwrd === false) { - return passwrd; - } else if (passwrd === null) { - return passwrd; - } - passwrd = passwrd.trim(); - if (passwrd.length < 1) { - if (!(session.cleanOutput)) { - warnUser("The password provided was blank."); - } - } - var sanitized = encodeURIComponent(passwrd);//.replace(/[\W]+/g, "_"); - //if (sanitized !== passwrd) { - // if (!(session.cleanOutput)) { - // warnUser("Info: Only AlphaNumeric characters should be used in the password.\n\nThe offending characters have been replaced by an underscore"); - // } - //} - return sanitized; -}; - -function isOperaGX(){ - return (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/75') >= 0; -} - -function getChromeVersion() { - var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./); - return raw ? parseInt(raw[2], 10) : false; -} - -if (!(getChromeVersion()>=57)){ - getById("effectSelector").disabled=true; - getById("effectSelector3").disabled=true; - getById("effectSelector").title = "Effects are only support on Chromium-based browsers"; - getById("effectSelector3").title = "Effects are only support on Chromium-based browsers"; - var elements = document.querySelectorAll('[data-effectsNotice]'); - for (let i = 0; i < elements.length; i++) { - elements[i].style.display = "inline-block"; - } -} - -function safariVersion() { - var ver = 0; - try { - ver = navigator.appVersion.split("Version/"); - if (ver.length > 1) { - ver = ver[1].split(" Safari"); - } - if (ver.length > 1) { - ver = ver[0].split("."); - } - if (ver.length > 1) { - ver = parseInt(ver[0]); - } else { - ver = 0; - } - } catch (e) { - return 0; - } - return ver; -} - -if (urlParams.has('optimize')) { - session.optimize = parseInt(urlParams.get('optimize')) || 0; -} -document.addEventListener("visibilitychange", function() { - log(document.hidden, document.visibilityState); - if ((iOS) || (iPad)) { // fixes a bug on iOS devices. Not need with other devices? - if (document.visibilityState === 'visible') { - setTimeout(function() { - resetupAudioOut(); - }, 500); - } - } -}); -function obsSceneChanged(event){ - log(event.detail.name); - window.obsstudio.getCurrentScene(function(scene) { - log("OBS SCENE"); - log(scene); - }); -} -function obsStreamingStarted(event){ - session.obsState.streaming = true; - session.obsStateSync(); -} -function obsStreamingStopped(event){ - session.obsState.streaming = false; - session.obsStateSync(); -} -function obsRecordingStarted(event){ - session.obsState.recording = true; - session.obsStateSync(); -} -function obsRecordingStopped(event){ - session.obsState.recording = false; - session.obsStateSync(); -} -function obsSourceActiveChanged(event){ - warnlog("obsSourceActiveChanged"); - warnlog( event.detail); - - try { - if (typeof event==="boolean"){var sourceActive = event;} - else if (typeof event.detail === "boolean"){var sourceActive = event.detail;} - else if (typeof event.detail.active === "boolean"){var sourceActive = event.detail.active;} - else {var sourceActive = event.detail.active;} - - if (typeof sourceActive === "undefined"){return;} // Just fail. - - if (session.obsState.sourceActive!==sourceActive){ // only move forward if there is a change; the event likes to double fire you see. - session.obsState.sourceActive = sourceActive; - session.obsStateSync(); - } - - } catch (e){errorlog(e);} -} - -function obsSourceVisibleChanged(event){ // accounts for visible in OBS.Ninja scene AND visible in OBS scene - warnlog("obsSourceVisibleChanged"); - warnlog(event.detail); - try { - if (typeof event==="boolean"){var visibility = event;} - else if (typeof event.detail === "boolean"){var visibility = event.detail;} - else if (typeof event.detail.visible === "boolean"){var visibility = event.detail.visible;} - else {var visibility = event.detail.visible;} - - if (typeof visibility === "undefined"){ // fall back - if (typeof document.visibilityState !== "undefined"){ - visibility = document.visibilityState==="visible"; // modern - } else if (typeof document.hidden !== "undefined"){ - visibility = !document.hidden; // legacy - } else { - return; // ... unknown input? fail. - } - } - - errorlog("visibility: "+visibility); - - if (session.obsState.visibility!==visibility){ // only move forward if there is a change; the event likes to double fire you see. - session.obsState.visibility = visibility; - session.obsStateSync(); - } - - } catch (e){errorlog(e);} -} - -if (window.obsstudio) { - session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? - session.audioMeterGuest = false; - session.audioEffects = false; - session.obsfix = 15; // can be manually set via URL. ; VP8=15, VP9=30. (previous was 20.) - try { - log("OBS VERSION:" + window.obsstudio.pluginVersion); - log("macOS: " + navigator.userAgent.indexOf('Mac OS X') != -1); - log(window.obsstudio); - - if (typeof document.visibilityState !== "undefined"){ - session.obsState.visibility = document.visibilityState==="visible"; - //session.obsState.sourceActive = session.obsState.visibility; - } - - window.obsstudio.getStatus(function(obsStatus) { - log("OBS STATUS:"); - log(obsStatus); - // TODO: update state here - if ("recording" in obsStatus){ - session.obsState.recording = obsStatus.recording; - } - if ("streaming" in obsStatus){ - session.obsState.streaming = obsStatus.streaming; - } - - }); - - if (!(urlParams.has('streamlabs'))) { - - var ver = window.obsstudio.pluginVersion; - ver1 = ver.split("."); - - var cefVersion = getChromeVersion(); - - if (ver1.length == 3) { // Should be 3, but disabled3 - if ((ver1.length == 3) && (parseInt(ver1[0]) == 2) && (cefVersion < 76) && (navigator.userAgent.indexOf('Mac OS X') != -1)) { - updateURL("streamlabs"); - getById("main").innerHTML = "

    Update OBS Studio to v26.1.2 or newer; older versions and StreamLabs OBS are not supported on macOS.\ -
    download here: https://github.com/obsproject/obs-studio/releases/tag/26.1.2\ -



    \ -

    Please use the Electron Capture app if there are further problems or if you wish to use StreamLabs on macOS still.

    \ -
    You can find more details within our wiki guide - https://github.com/steveseguin/obsninja/wiki/FAQ#mac-os\ -
    You can bypass this error message by refreshing, Clicking Here, or by adding &streamlabs to the URL, but it may still not actually work.\ - \ -
    Please report this problem to steve@seguin.email if you feel it is an error.\ -
    "; - } - } - } - - if (navigator.userAgent.indexOf('Mac OS X') != -1) { - session.codec = "h264"; // default the codec to h264 if OBS is on macOS (that's all it supports with hardware) - } - - if (session.disableOBS===false){ - window.addEventListener("obsSourceVisibleChanged", obsSourceVisibleChanged); - window.addEventListener("obsSourceActiveChanged", obsSourceActiveChanged); - window.addEventListener("obsSceneChanged", obsSceneChanged); - window.addEventListener("obsStreamingStarted", obsStreamingStarted); - window.addEventListener("obsStreamingStopped", obsStreamingStopped); - window.addEventListener("obsRecordingStarted", obsRecordingStarted); - window.addEventListener("obsRecordingStopped", obsRecordingStopped); - } - - } catch (e) { - errorlog(e); - } -} - -function manageSceneState(data, UUID){ - if (session.disableOBS){return;} - var processNeeded = false - try{ - if ("sceneDisplay" in data){ - processNeeded=true; - session.pcs[UUID].sceneDisplay = data.sceneDisplay; - } - if ("sceneMute" in data){ - processNeeded=true; - session.pcs[UUID].sceneMute = data.sceneMute; - } - if ("obsSourceActive" in data){ - processNeeded=true; - session.pcs[UUID].obsSourceActive = data.obsSourceActive; - } - if ("obsVisibility" in data){ - processNeeded=true; - session.pcs[UUID].obsVisibility = data.obsVisibility; - session.optimizeBitrate(UUID); // &optimize flag; sets video bitrate to target value if this flag == HIDDEN (if optimize=0, disables both audio and video) - } - if ("obsStreaming" in data){ - processNeeded=true; - session.pcs[UUID].obsStreaming = data.obsStreaming; - } - if ("obsRecording" in data){ - processNeeded=true; - session.pcs[UUID].obsRecording = data.obsRecording; - } - } catch(e){} // just in case the client has disconnected. - - if (processNeeded){ - applySceneState(); - } -} - -function applySceneState(){ - - if (session.cleanOutput===false){ - if (document.getElementById("videosource")){ - var visibility = false; - var ondeck = false; - var recording = false; - for (var uid in session.pcs){ - - if (session.pcs[uid].obsSourceActive && session.pcs[uid].obsVisibility && (session.pcs[uid].sceneDisplay!==false)){ - visibility=true; - } else if (session.pcs[uid].obsVisibility && (session.pcs[uid].sceneDisplay!==false)){ - ondeck=true; - } - if ((session.pcs[uid].obsRecording || session.pcs[uid].obsStreaming) && (session.pcs[uid].obsSourceActive && session.pcs[uid].obsVisibility && (session.pcs[uid].sceneDisplay!==false))){ // the scene that is recording must be visible also. - recording=true; - } - } - - if (recording){ - getById("obsState").classList.remove("ondeck"); - getById("obsState").classList.add("recording"); // TODO: this needs to check all peers to make sure it's valid - getById("obsState").innerHTML = "ON AIR"; - } else if (ondeck && !visibility){ - getById("obsState").classList.remove("recording"); - getById("obsState").classList.add("ondeck"); // TODO: this needs to check all peers to make sure it's valid - getById("obsState").innerHTML = "STAND BY"; - } else { - getById("obsState").classList.remove("recording"); - getById("obsState").classList.remove("ondeck"); - getById("obsState").innerHTML = "ACTIVE"; - } - - if (visibility || ondeck){ // BASIC TALLY LIGHT - getById("obsState").classList.add("onair"); // LIVE - } else { - getById("obsState").classList.remove("onair"); - - } - - } - } - -} - -window.onload = function winonLoad() { // This just keeps people from killing the live stream accidentally. Also give me a headsup that the stream is ending - window.addEventListener("beforeunload", function(e) { - try { - session.ws.close(); - if (session.videoElement.recording) { - session.videoElement.recorder.writer.close(); - session.videoElement.recording = false; - } - for (var i in session.rpcs) { - if (session.rpcs[i].videoElement) { - if (session.rpcs[i].videoElement.recording) { - session.rpcs[i].videoElement.recorder.writer.close(); - session.rpcs[i].videoElement.recording = false; - } - } - } - } catch (e) {} - //setTimeout(function(){session.hangup();},0); - return undefined; // ADDED OCT 29th; get rid of popup. Just close the socket connection if the user is refreshing the page. It's one or the other. - - }); -}; - -getById("credits").innerHTML = "Version: " + session.version + " - " + getById("credits").innerHTML; - -var lastTouchEnd = 0; -document.addEventListener('touchend', function(event) { - var now = (new Date()).getTime(); - if (now - lastTouchEnd <= 300) { - event.preventDefault(); - } - lastTouchEnd = now; -}, false); - - -document.addEventListener('click', function(event) { - if (session.firstPlayTriggered == false) { - playAllVideos(); - session.firstPlayTriggered = true; - history.pushState({}, ''); - } -}); -var Callbacks = []; -var CtrlPressed = false; // global -var AltPressed = false; -document.addEventListener("keydown", event => { - - if ((event.ctrlKey) || (event.metaKey)) { // detect if CTRL is pressed - CtrlPressed = true; - } else { - CtrlPressed = false; - } - if (event.altKey) { - AltPressed = true; - } else { - AltPressed = false; - } - - - if (CtrlPressed && event.keyCode) { - - if (event.keyCode == 77) { // m - if (event.metaKey) { - if (AltPressed) { - toggleMute(); // macOS - } - } else { - toggleMute(); // Windows - } - // } else if (event.keyCode == 69) { // e - // hangup(); - } else if (event.keyCode == 66) { // b - toggleVideoMute(); - } - } - - -}); - -document.addEventListener("keyup", event => { - if (!((event.ctrlKey) || (event.metaKey))) { - if (CtrlPressed) { - CtrlPressed = false; - for (var i in Callbacks) { - var cb = Callbacks[i]; - log(cb.slice(1)); - cb[0](...cb.slice(1)); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#A_better_apply - } - Callbacks = []; - } - } - if (!(event.altKey)) { - AltPressed = false; - } -}); - -window.onpopstate = function() { - if (session.firstPlayTriggered) { - window.location.reload(true); - } -}; - -if (typeof session === 'undefined') { // make sure to init the WebRTC if not exists. - var session = WebRTC.Media; - session.streamID = session.generateStreamID(); - errorlog("Serious error: WebRTC session didn't load in time"); -} - -if (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1) { - try { - getById("electronDragZone").style.cursor="grab"; - const ipcRenderer = require('electron').ipcRenderer; - window.prompt = function(title, val){ - return ipcRenderer.sendSync('prompt', {title, val}); - }; - } catch(e){} -} - -function makeDraggableElement(elmnt) { - try { - elmnt.dragElement = false; - elmnt.style.bottom = "auto"; - elmnt.style.cursor = "grab"; - elmnt.stashonmouseup = null; - elmnt.stashonmousemove = null; - - } catch (e) { - errorlog(e); - return; - } - - var pos1 = 0; - var pos2 = 0; - var pos3 = 0; - var pos4 = 0; - - function dragMouseDown(e) { - e = e || window.event; - e.preventDefault(); - - pos3 = e.clientX; - pos4 = e.clientY; - elmnt.stashonmouseup = document.onmouseup; // I don't want to interfere with other drag events. - elmnt.stashonmousemove = document.onmousemove; - - document.onmouseup = closeDragElement; - document.onmousemove = elementDrag; - } - - function elementDrag(e) { - e = e || window.event; - e.preventDefault(); - - elmnt.dragElement = true; - pos1 = pos3 - e.clientX; - pos2 = pos4 - e.clientY; - pos3 = e.clientX; - pos4 = e.clientY; - - var topDrag = (elmnt.offsetTop - pos2); - if (topDrag > -3) { - topDrag = -3; - } - elmnt.style.top = topDrag + "px"; - elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; - - } - - elmnt.onmousedown = dragMouseDown; - function closeDragElement() { - document.onmouseup = elmnt.stashonmouseup; - document.onmousemove = elmnt.stashonmousemove; - } -} - -function setStorage(cname, cvalue, exdays=999) { // not actually a cookie - var now = new Date(); - var item = { - value: cvalue, - expiry: now.getTime() + (exdays * 24 * 60 * 60 * 1000), - }; - localStorage.setItem(cname, JSON.stringify(item)); -} - -function getStorage(cname) { - var itemStr = localStorage.getItem(cname); - if (!itemStr) { - return ""; - } - var item = JSON.parse(itemStr); - var now = new Date(); - if (now.getTime() > item.expiry) { - localStorage.removeItem(cname); - return ""; - } - return item.value; -} - -if (!isIFrame){ - if (getStorage("redirect") == "yes") { - setStorage("redirect", "", 0); - session.sticky = true; - } else if (getStorage("settings") != "") { - if (!(session.cleanOutput)){ - window.focus(); - session.sticky = confirm("Would you like you load your previous session's settings?"); - if (!session.sticky) { - setStorage("settings", "", 0); - log("deleting cookie as user said no"); - } else { - var cookieSettings = decodeURI(getStorage("settings")); - setStorage("redirect", "yes", 1); - window.location.replace(cookieSettings); - } - } - } - - if (urlParams.has('sticky')){ // won't work with iframes. - - //if (getStorage("permission") == "") { - // session.sticky = confirm("Would you allow us to store a cookie to keep your session settings persistent?"); - //} else { - session.sticky = true; - //} - //if (session.sticky) { - setStorage("permission", "yes", 999); - setStorage("settings", encodeURI(window.location.href), 90); - //} - } -} - -if (urlParams.has('cleanoutput') || urlParams.has('clean') || urlParams.has('cleanish')) { - session.cleanOutput = true; -} - -if (urlParams.has('retrytimeout')) { - session.retryTimeout = parseInt(urlParams.get('retrytimeout')); -} - -if (urlParams.has('ptz')){ - session.ptz=true; -} - -var screensharebutton = true; -var screensharesupport = true; -if (urlParams.has('nosettings') || urlParams.has('ns')) { - screensharebutton = false; - session.showSettings = false; -} - -if (urlParams.has('nomicbutton') || urlParams.has('nmb')) { - getById("mutebutton").setAttribute('style', "display: none !important"); -} - - -if (urlParams.has('novideobutton') || urlParams.has('nvb')) { - getById("mutevideobutton").setAttribute('style', "display: none !important"); -} - -if (urlParams.has('screenshareid') || urlParams.has('ssid')) { - if (urlParams.get('screenshareid') || urlParams.get('ssid')) { - session.screenshareid = urlParams.get('screenshareid') || urlParams.get('ssid'); - session.screenshareid = sanitizeStreamID(session.screenshareid); - } -} - -if (urlParams.has('screensharefps') || urlParams.has('ssfps')) { - if (urlParams.get('screensharefps') || urlParams.get('ssfps')) { - session.screensharefps = urlParams.get('screensharefps') || urlParams.get('ssfps'); - session.screensharefps = parseInt(session.screensharefps) || 2; - } -} - -if (urlParams.has('screensharequality') || urlParams.has('ssq')) { - if (urlParams.get('screensharequality') || urlParams.get('ssq')) { - session.screensharequality = urlParams.get('screensharequality') || urlParams.get('ssq'); - session.screensharequality = parseInt(session.screensharequality) || 1; - } -} - -if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { - //session.webcamonly = true; - session.mobile = true; - getById("shareScreenGear").style.display = "none"; - screensharebutton = false; - screensharesupport = false; - getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("dropButton").style.display = "none"; - //session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? - session.audioEffects = false; // disable audio inbound effects also. - session.audioMeterGuest = false; - -} else if ((iOS) || (iPad)) { - getById("shareScreenGear").style.display = "none"; - session.mobile = true; - screensharebutton = false; - screensharesupport = false; - getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("dropButton").style.display = "none"; - //session.audiobitrate = false; // iOS devices seem to get distortion with custom audio bitrates. Disable for now. - //session.maxiosbitrate = 10; // this is 10-kbps by default already. - //session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? - session.audioEffects = false; // disable audio inbound effects also. - session.audioMeterGuest = false; -} else { - log("MAKE DRAGGABLE"); - setTimeout(function(){makeDraggableElement(document.getElementById("subControlButtons"));},100); - - if (safariVersion() && !getChromeVersion()){ - getById("SafariWarning").style.display = "block"; - } -} - - -if ((iOS) || (iPad)) { - window.addEventListener('resize', function() { // Safari is the new IE. - var msg = {}; - msg.requestSceneUpdate = true; - session.sendMessage(msg); - - if ( window.matchMedia("(orientation: portrait)").matches ) { - document.getElementsByTagName("html")[0].style.height = "100vh"; - setTimeout(function(){ - document.getElementsByTagName("html")[0].style.height = "100%"; - }, 1000); - } else if ( window.matchMedia("(orientation: landscape)").matches ) { - document.getElementsByTagName("html")[0].style.height = "100vh"; - setTimeout(function(){ - document.getElementsByTagName("html")[0].style.height = "100%"; - }, 1000); - } - }); -} - -if (/CriOS/i.test(navigator.userAgent) && (iOS || iPad)) { - if (!(session.cleanOutput)) { - try { - navigator.mediaDevices.getUserMedia; - } catch (e) { - warnUser("Chrome on this device does not support the required technology to use this site.\n\nPlease use Safari instead or update your iOS and browser version."); - } - } -} - -if (urlParams.has('broadcast') || urlParams.has('bc')) { - log("Broadcast flag set"); - session.broadcast = urlParams.get('broadcast') || urlParams.get('bc') || null; - //if ((iOS) || (iPad)) { - // session.nopreview = false; - //} else { - // session.nopreview = true; - //} - session.minipreview = 2; // full screen if nothing else on screen. - session.style = 1; - getById("header").style.display = "none"; - getById("header").style.opacity = 0; - session.showList=false; -} - -if (urlParams.has('showlist')) { - session.showList = urlParams.get('showlist'); - if (session.showList === "false") { - session.showList = false; - } else if (session.showList=== "0") { - session.showList = false; - } else if (session.showList === "no") { - session.showList = false; - } else if (session.showList === "off") { - session.showList = false; - } else { - session.showList = true; - } -} - -var directorLanding = false; -if (urlParams.has('director') || urlParams.has('dir')) { - directorLanding = urlParams.get('director') || urlParams.get('dir') || null; - if (directorLanding === null) { - directorLanding = true; - } else if (directorLanding.length === 0) { - directorLanding = true; - } else { - directorLanding = false; - } - session.meterStyle = 1; -} else if (filename === "director") { - directorLanding = true; - filename = false; - session.meterStyle = 1; -} - -if (urlParams.has('rooms')) { - session.rooms = urlParams.get('rooms').split(",").map(function(e) { - return sanitizeRoomName(e); - }); - getById("rooms").classList.remove('advanced'); -} - -if (urlParams.has('showdirector')) { - session.showDirector = true; -} - -if (urlParams.has('midi') || urlParams.has('hotkeys')) { - session.midiHotkeys = urlParams.get('midi') || urlParams.get ('hotkeys') || 1; - session.midiHotkeys = parseInt(session.midiHotkeys); -} - -if (urlParams.has('midipush') || urlParams.has('midiout') || urlParams.has('mo')){ - session.midiOut = urlParams.get('midipush') || urlParams.get('midiout') || urlParams.get('mo') || true; -} - -if (urlParams.has('midipull') || urlParams.has('midiin') || urlParams.has('mi')){ - session.midiIn = urlParams.get('midipull') || urlParams.get('midiin') || urlParams.get('mi') || true; -} - -var loadedQRCode = false; -function loadQR(){ - if (loadedQRCode==false){ - loadedQRCode=true; - var script = document.createElement('script'); - script.src = "./thirdparty/qrcode.min.js"; // dynamically load this only if its needed. Keeps loading time down. - document.head.appendChild(script); - } -} - -if (urlParams.has('webcam') || urlParams.has('wc')) { - session.webcamonly = true; - screensharebutton = false; -} else if (urlParams.has('screenshare') || urlParams.has('ss')) { - session.screenshare = true; -} else if (urlParams.has('fileshare') || urlParams.has('fs')) { - getById("container-5").classList.remove('advanced'); - getById("container-5").classList.add("skip-animation"); - getById("container-5").classList.remove('pointer'); -} else if (directorLanding) { - getById("container-1").classList.remove('advanced'); - getById("container-1").classList.add("skip-animation"); - getById("container-1").classList.remove('pointer'); -} else if (urlParams.has('website') || urlParams.has('iframe')) { - getById("container-6").classList.remove('advanced'); - getById("container-6").classList.add("skip-animation"); - getById("container-6").classList.remove('pointer'); - session.website = urlParams.get('website') || urlParams.get('iframe') || false; - - if (session.website){ - if (session.director){ - setTimeout(function(){shareWebsite(session.website);},100); - } else { - setTimeout(function(){session.publishIFrame(session.website);},100); - - } - } -} - - -if (urlParams.has('ssb')) { - screensharebutton = true; -} - -if (urlParams.has('mute') || urlParams.has('muted') || urlParams.has('m')) { - session.muted = true; -} - -if (urlParams.has('videomute') || urlParams.has('videomuted') || urlParams.has('vm')) { - session.videoMutedFlag = true; -} - - -if (urlParams.has('deaf') || urlParams.has('deafen')) { - session.directorSpeakerMuted=true; // false == true in this case. -} - -if (urlParams.has('blind')) { - session.directorDisplayMuted=true; // false == true in this case. -} - - -if (urlParams.has('dpi') || urlParams.has('dpr')) { - session.devicePixelRatio = urlParams.get('dpi') || urlParams.get('dpr') || 2.0; -} //else if (window.devicePixelRatio && window.devicePixelRatio!==1){ -// session.devicePixelRatio = window.devicePixelRatio; // this annoys me to no end. -//} - -if (urlParams.has('speakermute') || urlParams.has('mutespeaker') || urlParams.has('sm') || urlParams.has('ms')) { - session.speakerMuted = true; - getById("mutespeakertoggle").className = "las la-volume-mute my-float toggleSize"; - //getById("mutespeakerbutton").className="advanced float2 red"; - getById("mutespeakerbutton").classList.add("red"); - getById("mutespeakerbutton").classList.add("float2"); - getById("mutespeakerbutton").classList.remove("float"); - - var sounds = document.getElementsByTagName("video"); - for (var i = 0; i < sounds.length; ++i) { - sounds[i].muted = session.speakerMuted; - } -} - -if (urlParams.has('chatbutton') || urlParams.has('chat') || urlParams.has('cb')) { - session.chatbutton = urlParams.get('chatbutton') || urlParams.get('chat') || urlParams.get('cb') || null; - if (session.chatbutton === "false") { - session.chatbutton = false; - } else if (session.chatbutton === "0") { - session.chatbutton = false; - } else if (session.chatbutton === "no") { - session.chatbutton = false; - } else if (session.chatbutton === "off") { - session.chatbutton = false; - } else { - session.chatbutton = true; - getById("chatbutton").classList.remove("advanced"); - getById("controlButtons").style.display = "inherit"; - } -} - -if (session.screenshare == true) { - getById("container-3").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("container-2").classList.add("skip-animation"); - getById("container-2").classList.remove('pointer'); -} - -if (urlParams.has('manual')) { - session.manual = true; -} - -if (urlParams.has('hands') || urlParams.has('hand')) { - session.raisehands = true; -} - -if (urlParams.has('portrait') || urlParams.has('916') || urlParams.has('vertical')) { - session.aspectratio = 1; // 9:16 (default of 0 is 16:9) -} else if (urlParams.has('square') || urlParams.has('11')) { - session.aspectratio = 2; //1:1 ? -} - -if (urlParams.has('cover')) { - session.cover = true; - document.documentElement.style.setProperty('--fit-style', 'cover'); -} - -if (urlParams.has('record')) { - if (safariVersion()) { - if (!(session.cleanOutput)) { - warnUser("Your browser or device is not supported. Try Chrome if on macOS."); - } - } else { - session.recordLocal = urlParams.get('record'); - - if (session.recordLocal !== parseInt(session.recordLocal)) { - session.recordLocal = 6000; - } else { - session.recordLocal = parseInt(session.recordLocal); - } - } -} -if (urlParams.has('pcm')) { - session.pcm = true; -} - -if (urlParams.has('bigbutton')) { - session.bigmutebutton = true; - getById("mutebutton").style.width = "min(40vh,40vw)"; - getById("mutebutton").style.height = "min(40vh,40vw)"; - getById("mutetoggle").style.width = "min(40vh,40vw)"; - getById("mutetoggle").style.height = "min(40vh,40vw)"; - -} - -if (urlParams.has('scene')) { - session.scene = urlParams.get('scene') || 0; - if (typeof session.scene === "string"){ - session.scene = session.scene.replace(/[\W]+/g, "_"); - } else { - session.scene = (parseInt(session.scene) || 0) + ""; - - } - session.disableWebAudio = true; - session.audioEffects = false; - session.audioMeterGuest = false; -} -if (session.scene!=="1"){ // scene =0 and 1 should load instantly. - session.hiddenSceneViewBitrate = 0; // By default this is ~ 400kbps, but if you have 10 scenes, i don't want to kill things. -} - -if (urlParams.has('scenetype') || urlParams.has('type')) { - session.sceneType = parseInt(urlParams.get('scenetype')) || parseInt(urlParams.get('type')) || false; -} - -if (urlParams.has('mediasettings')) { - session.forceMediaSettings = true; -} - - -if (urlParams.has('transcript') || urlParams.has('transcribe') || urlParams.has('trans')) { - session.transcript = urlParams.get('transcript') || urlParams.get('transcribe') || urlParams.get('trans') || "en-US"; -} - - -if (urlParams.has('cc') || urlParams.has('closedcaptions') || urlParams.has('captions')) { - session.closedCaptions = true; -} - -if (session.webcamonly == true) { - getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("container-3").classList.add("skip-animation"); - getById("container-3").classList.remove('pointer'); - setTimeout(function() { - previewWebcam(); - }, 100); -} - -if (urlParams.has('css')){ - var cssURL = urlParams.get('css'); - cssURL = decodeURI(cssURL); - log(cssURL); - var cssStylesheet = document.createElement('link'); - cssStylesheet.rel = 'stylesheet'; - cssStylesheet.type = 'text/css'; - cssStylesheet.media = 'screen'; - cssStylesheet.href = cssURL; - document.getElementsByTagName('head')[0].appendChild(cssStylesheet); - - cssStylesheet.onload = function() { - getById("main").classList.remove('hidden'); - log("loaded remote style sheet"); - }; - - cssStylesheet.onerror = function() { - getById("main").classList.remove('hidden'); - errorlog("REMOTE STYLE SHEET HAD ERROR"); - }; - -} else { - getById("main").classList.remove('hidden'); -} - -if (urlParams.has('password') || urlParams.has('pass') || urlParams.has('pw') || urlParams.has('p')) { - session.password = urlParams.get('password') || urlParams.get('pass') || urlParams.get('pw') || urlParams.get('p'); - if (!session.password) { - window.focus(); - session.password = prompt("Please enter the password below: \n\n(Note: Passwords are case-sensitive and you will not be alerted if it is incorrect.)"); - } else if (session.password === "false") { - session.password = false; - session.defaultPassword = false; - } else if (session.password === "0") { - session.password = false; - session.defaultPassword = false; - } else if (session.password === "off") { - session.password = false; - session.defaultPassword = false; - } -} - -if (session.password) { - session.password = sanitizePassword(session.password); - getById("passwordRoom").value = session.password; - session.defaultPassword = false; - getById("addPasswordBasic").style.display = "none"; -} - - -if (urlParams.has('hash') || urlParams.has('crc') || urlParams.has('check')) { // could be brute forced in theory, so not as safe as just not using a hash check. - session.taintedSession = null; // waiting to see if valid or not. - var hash_input = urlParams.get('hash') || urlParams.get('crc') || urlParams.get('check'); - if (session.password === false) { - window.focus(); - session.password = prompt("Please enter the password below: \n\n(Note: Passwords are case-sensitive.)"); - session.password = sanitizePassword(session.password); - getById("passwordRoom").value = session.password; - session.defaultPassword = false; - } - - session.generateHash(session.password + session.salt, 6).then(function(hash) { // million to one error. - log("hash is " + hash); - if (hash.substring(0, 4) !== hash_input) { // hash crc checks are just first 4 characters. - session.taintedSession = true; - if (!(session.cleanOutput)) { - getById("request_info_prompt").innerHTML = "The password was incorrect.\n\nRefresh and try again."; - getById("request_info_prompt").style.display = "block"; - getById("mainmenu").style.display = "none"; - getById("head1").style.display = "none"; - session.cleanOutput = true; - - } else { - getById("request_info_prompt").innerHTML = ""; - getById("request_info_prompt").style.display = "block"; - getById("mainmenu").style.display = "none"; - getById("head1").style.display = "none"; - } - } else { - session.taintedSession = false; - session.hash = hash; - } - }); -} - -if (session.defaultPassword !== false) { - session.password = session.defaultPassword; // no user entered password; let's use the default password if its not disabled. -} - -if (urlParams.has('showlabels') || urlParams.has('showlabel') || urlParams.has('sl')) { - session.showlabels = urlParams.get('showlabels') || urlParams.get('showlabel') || urlParams.get('sl') || ""; - session.showlabels = sanitizeLabel(session.showlabels.replace(/[\W]+/g, "_").replace(/_+/g, '_')); - if (session.showlabels == "") { - session.showlabels = true; - session.labelstyle = false; - } else { - session.labelstyle = session.showlabels; - session.showlabels = true; - } -} - -if (urlParams.has('sizelabel') || urlParams.has('labelsize') || urlParams.has('fontsize')) { - session.labelsize = urlParams.get('sizelabel') || urlParams.get('labelsize') || urlParams.get('fontsize') || 100; - session.labelsize = parseInt(session.labelsize); -} - -if (urlParams.has('label') || urlParams.has('l')) { - session.label = urlParams.get('label') || urlParams.get('l') || null; - var updateURLAsNeed = true; - if (session.label == null || session.label.length == 0) { - window.focus(); - session.label = prompt("Please enter your display name:"); - } else { - var updateURLAsNeed = false; - session.label = decodeURIComponent(session.label); - session.label = session.label.replace(/_/g, " ") - } - if (session.label != null) { - session.label = sanitizeLabel(session.label); // alphanumeric was too strict. - document.title = session.label; // what the result is. - - if (updateURLAsNeed) { - var label = encodeURIComponent(session.label); - if (urlParams.has('l')) { - updateURL("l=" + label, true, false); - } else { - updateURL("label=" + label, true, false); - } - } - } -} - -if (urlParams.has('transparent')) { // sets the window to be transparent - useful for IFRAMES? - getById("main").style.backgroundColor = "rgba(0,0,0,0)"; - document.documentElement.style.setProperty('--container-color', '#0000'); - document.documentElement.style.setProperty('--background-color', '#0000'); - document.documentElement.style.setProperty('--regular-margin', '0'); - document.documentElement.style.setProperty('--director-margin', '0 25px 0 0'); - getById("directorLinksButton").style.color = "black"; - session.transparent=true; -} - -if (urlParams.has('stereo') || urlParams.has('s') || urlParams.has('proaudio')) { // both peers need this enabled for HD stereo to be on. If just pub, you get no echo/noise cancellation. if just viewer, you get high bitrate mono - log("STEREO ENABLED"); - session.stereo = urlParams.get('stereo') || urlParams.get('s') || urlParams.get('proaudio'); - - if (session.stereo) { - session.stereo = session.stereo.toLowerCase(); - } - - //var supportedConstraints = navigator.mediaDevices.getSupportedConstraints(); - //supportedConstraints.channelCount; - - if (session.stereo === "false") { - session.stereo = 0; - session.audioInputChannels = 1; - } else if (session.stereo === "0") { - session.stereo = 0; - session.audioInputChannels = 1; - } else if (session.stereo === "no") { - session.stereo = 0; - session.audioInputChannels = 1; - } else if (session.stereo === "off") { - session.stereo = 0; - session.audioInputChannels = 1; - - } else if (session.stereo === "1") { - session.stereo = 1; - } else if (session.stereo === "both") { - session.stereo = 1; - } else if (session.stereo === "3") { - session.stereo = 3; - } else if (session.stereo === "out") { - session.stereo = 3; - } else if (session.stereo === "mono") { - session.stereo = 3; - session.audiobitrate = 128; - } else if (session.stereo === "4") { - session.stereo = 4; - } else if (session.stereo === "multi") { - session.stereo = 4; - } else if (session.stereo === "2") { - session.stereo = 2; - } else if (session.stereo === "in") { - session.stereo = 2; - } else { - session.stereo = 5; // guests; no stereo in, no high bitrate in, but otherwise like stereo=1 - } -} - - -if (urlParams.has('pie')){ - session.pie = urlParams.get('pie') || false; // If session.pie == true, then there is no need to set parameters via URL - if (session.pie){ - session.wss = "wss://us-nyc-1.websocket.me/v3/1?api_key="+session.pie; // if URL param is set, it will use the API key. - } -} - -if ((session.stereo == 1) || (session.stereo == 3) || (session.stereo == 4) || (session.stereo == 5)) { - session.echoCancellation = false; - session.autoGainControl = false; - session.noiseSuppression = false; -} - -if (urlParams.has('mono')) { - session.mono = true; - if ((session.stereo == 1) || (session.stereo == 4)) { - session.stereo = 3; - session.audiobitrate = 128; - } else if (session.stereo == 5) { - session.stereo = 3; - session.audiobitrate = 128; - } else if (session.stereo == 2) { - session.stereo = 0; - session.audiobitrate = 128; - } -} - -if (urlParams.has("channelcount") || urlParams.has("ac")) { - session.audioInputChannels = urlParams.get('channelcount') || urlParams.get('ac'); - session.audioInputChannels = parseInt(session.audioInputChannels); - if (!session.audioInputChannels) { - session.audioInputChannels = false; - } -} - - -if (urlParams.has("aec") || urlParams.has("ec")) { - - session.echoCancellation = urlParams.get('aec') || urlParams.get('ec'); - - if (session.echoCancellation) { - session.echoCancellation = session.echoCancellation.toLowerCase(); - } - if (session.echoCancellation == "false") { - session.echoCancellation = false; - } else if (session.echoCancellation == "0") { - session.echoCancellation = false; - } else if (session.echoCancellation == "no") { - session.echoCancellation = false; - } else if (session.echoCancellation == "off") { - session.echoCancellation = false; - } else { - session.echoCancellation = true; - } -} - - -if (urlParams.has("autogain") || urlParams.has("ag")) { - - session.autoGainControl = urlParams.get('autogain') || urlParams.get('ag'); - if (session.autoGainControl) { - session.autoGainControl = session.autoGainControl.toLowerCase(); - } - if (session.autoGainControl == "false") { - session.autoGainControl = false; - } else if (session.autoGainControl == "0") { - session.autoGainControl = false; - } else if (session.autoGainControl == "no") { - session.autoGainControl = false; - } else if (session.autoGainControl == "off") { - session.autoGainControl = false; - } else { - session.autoGainControl = true; - } -} - -if (urlParams.has("denoise") || urlParams.has("dn")) { - - session.noiseSuppression = urlParams.get('denoise') || urlParams.get('dn'); - - if (session.noiseSuppression) { - session.noiseSuppression = session.noiseSuppression.toLowerCase(); - } - if (session.noiseSuppression == "false") { - session.noiseSuppression = false; - } else if (session.noiseSuppression == "0") { - session.noiseSuppression = false; - } else if (session.noiseSuppression == "no") { - session.noiseSuppression = false; - } else if (session.noiseSuppression == "off") { - session.noiseSuppression = false; - } else { - session.noiseSuppression = true; - } -} - - -if (urlParams.has('roombitrate') || urlParams.has('roomvideobitrate') || urlParams.has('rbr')) { - log("Room BITRATE SET"); - session.roombitrate = urlParams.get('roombitrate') || urlParams.get('rbr') || urlParams.get('roomvideobitrate'); - session.roombitrate = parseInt(session.roombitrate); - if (session.roombitrate < 1) { - session.roombitrate = 0; - } -} - -if ( urlParams.has('outboundaudiobitrate') || urlParams.has('oab')) { - session.outboundAudioBitrate = parseInt(urlParams.get('outboundaudiobitrate')) || parseInt(urlParams.get('oab')) || false; -} -if (urlParams.has('outboundvideobitrate') || urlParams.has('ovb')) { - session.outboundVideoBitrate = parseInt(urlParams.get('outboundvideobitrate')) || parseInt(urlParams.get('ovb')) || false; -} - -if (urlParams.has('webp')){ - session.webp = true; -} - -if (urlParams.has('webpquality') || urlParams.has('webpq') || urlParams.has('wq')){ - session.webPquality = parseInt(urlParams.get('webpquality')) || parseInt(urlParams.get('webpq')) || parseInt(urlParams.get('wq')) || 4; -} - - -if (urlParams.has('audiobitrate') || urlParams.has('ab')) { // both peers need this enabled for HD stereo to be on. If just pub, you get no echo/noise cancellation. if just viewer, you get high bitrate mono - log("AUDIO BITRATE SET"); - session.audiobitrate = urlParams.get('audiobitrate') || urlParams.get('ab'); - session.audiobitrate = parseInt(session.audiobitrate); - if (session.audiobitrate < 1) { - session.audiobitrate = false; - } else if (session.audiobitrate > 510) { - session.audiobitrate = 510; - } // this is to just prevent abuse -} -if ((iOS) || (iPad)) { - session.audiobitrate = false; // iOS devices seem to get distortion with custom audio bitrates. Disable for now. -} - -/* if (urlParams.has('whitebalance') || urlParams.has('temp')){ // Need to be applied after the camera is selected. bleh. not enforcible. remove for now. - var temperature = urlParams.get('whitebalance') || urlParams.get('temp'); - try{ - updateCameraConstraints('colorTemperature', parseFloat(temperature)); - } catch (e){errorlog(e);} -} */ - -if (urlParams.has('streamid') || urlParams.has('view') || urlParams.has('v') || urlParams.has('pull')) { // the streams we want to view; if set, but let blank, we will request no streams to watch. - session.view = urlParams.get('streamid') || urlParams.get('view') || urlParams.get('v') || urlParams.get('pull') || null; // this value can be comma seperated for multiple streams to pull - - getById("headphonesDiv2").style.display = "inline-block"; - getById("headphonesDiv").style.display = "inline-block"; - getById("addPasswordBasic").style.display = "none"; - - if (session.view == null) { - session.view = ""; - } - if (session.view) { - if (session.view.split(",").length > 1) { - session.view_set = session.view.split(","); - } - } -} - -//if (urlParams.has('directorview') || urlParams.has('dv')){ -// session.directorView = true; -// if (!session.view){ -// session.view = true; -// } -//} - -if (urlParams.has('nopreview') || urlParams.has('np')) { - log("preview OFF"); - session.nopreview = true; -} else if ((urlParams.has('preview')) || (urlParams.has('showpreview'))) { - log("preview ON"); - session.nopreview = false; -} else if ((urlParams.has('minipreview')) || (urlParams.has('mini'))) { - var mini = urlParams.has('minipreview') || urlParams.has('mini') || true; // 2 is a valid option. - log("preview ON"); - session.nopreview = false; - session.minipreview = mini; -} - -if (urlParams.has('obsfix')) { - session.obsfix = urlParams.get('obsfix'); - if (session.obsfix) { - session.obsfix = session.obsfix.toLowerCase(); - } - if (session.obsfix == "false") { - session.obsfix = false; - } else if (session.obsfix == "0") { - session.obsfix = false; - } else if (session.obsfix == "no") { - session.obsfix = false; - } else if (session.obsfix == "off") { - session.obsfix = false; - } else if (parseInt(session.obsfix) > 0) { - session.obsfix = parseInt(session.obsfix); - } else { - session.obsfix = 1; // aggressive. - } -} - -if (urlParams.has('controlroombitrate') || urlParams.has('crb')) { - session.controlRoomBitrate = true; -} - -if (urlParams.has('remote') || urlParams.has('rem')) { - log("remote ENABLED"); - session.remote = urlParams.get('remote') || urlParams.get('rem') || "nosecurity"; - session.remote = session.remote.trim(); -} - -if (urlParams.has('latency') || urlParams.has('al') || urlParams.has('audiolatency')) { - log("latency ENABLED"); - session.audioLatency = urlParams.get('latency') || urlParams.get('al') || urlParams.get('audiolatency'); - session.audioLatency = parseInt(session.audioLatency) || 0; - session.disableWebAudio = false; -} - - - -if (urlParams.has('micdelay') || urlParams.has('delay') || urlParams.has('md')) { - log("audio gain ENABLED"); - session.micDelay = urlParams.get('micdelay') || urlParams.get('delay') || urlParams.get('md'); - session.micDelay = parseInt(session.micDelay) || 0; - session.disableWebAudio = false; -} - -if (urlParams.has('tips')){ - getById("guestTips").style.display="flex"; -} - -if (urlParams.has('audiogain') || urlParams.has('gain') || urlParams.has('g')) { - log("audio gain ENABLED"); - session.audioGain = urlParams.get('audiogain') || urlParams.get('gain') || urlParams.get('g'); - session.audioGain = parseInt(session.audioGain) || 0; - session.disableWebAudio = false; -} -if (urlParams.has('compressor') || urlParams.has('comp')) { - log("audio gain ENABLED"); - session.compressor = 1; - session.disableWebAudio = false; -} else if (urlParams.has('limiter')) { - log("audio gain ENABLED"); - session.compressor = 2; - session.disableWebAudio = false; -} -if ((urlParams.has('equalizer')) || (urlParams.has('eq'))) { - session.equalizer = true; - session.disableWebAudio = false; -} -if ((urlParams.has('lowcut')) || (urlParams.has('lc')) || (urlParams.has('higpass'))) { - session.lowcut = urlParams.get('lowcut') || urlParams.get('lc') || urlParams.get('higpass') || 100; - session.lowcut = parseInt(session.lowcut); - session.disableWebAudio = false; -} - -if (urlParams.has('pip')) { - session.pip = true; // togglePip - //session.manual=true; - //innerHTML = -} - -if (urlParams.has('keyframeinterval') || urlParams.has('keyframerate') || urlParams.has('keyframe') || urlParams.has('fki')) { - log("keyframerate ENABLED"); - session.keyframerate = parseInt(urlParams.get('keyframeinterval') || urlParams.get('keyframerate') || urlParams.get('keyframe') || urlParams.get('fki')) || 0; -} - -if (urlParams.has('tallyoff') || urlParams.has('obsoff') || urlParams.has('oo')) { - log("OBS feedback disabled"); - session.disableOBS = true; -} - - -if (urlParams.has('chroma')) { - log("Chroma ENABLED"); - getById("main").style.backgroundColor = "#" + (urlParams.get('chroma') || "0F0"); -} - -if (urlParams.has('margin')) { - if (urlParams.get('margin') || 10){ - try { - var videoMargin = urlParams.get('margin') || 10; - videoMargin = parseInt(videoMargin); - videoMargin+="px"; - document.querySelector(':root').style.setProperty('--video-margin', videoMargin); - } catch(e){errorlog("variable css failed");} - } -} - -if (urlParams.has('fadein')) { - if (urlParams.get('fadein') || 0){ - try { - var fadeinspeed = parseInt(urlParams.get('fadein') || 0)/1000.0; - fadeinspeed+="s"; - document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed); - } catch(e){errorlog("variable css failed");} - } else { - try { - var fadeinspeed = 0.5; - fadeinspeed+="s"; - document.querySelector(':root').style.setProperty('--fadein-speed', fadeinspeed); - } catch(e){errorlog("variable css failed");} - } -} - - -if (urlParams.has("videodevice") || urlParams.has("vdevice") || urlParams.has('vd') || urlParams.has('device') || urlParams.has('d')) { - - session.videoDevice = urlParams.get("videodevice") || urlParams.get("vdevice") || urlParams.get("vd") || urlParams.get("device") || urlParams.get("d"); - - if (session.videoDevice === null) { - session.videoDevice = "1"; - } else if (session.videoDevice) { - session.videoDevice = session.videoDevice.toLowerCase().replace(/[\W]+/g, "_"); - } - if (session.videoDevice == "false") { - session.videoDevice = 0; - } else if (session.videoDevice == "0") { - session.videoDevice = 0; - } else if (session.videoDevice == "no") { - session.videoDevice = 0; - } else if (session.videoDevice == "off") { - session.videoDevice = 0; - } else if (session.videoDevice == "snapcam") { - session.videoDevice = "snap_camera"; - } else if (session.videoDevice == "canon") { - session.videoDevice = "eos"; - } else if (session.videoDevice == "camlink") { - session.videoDevice = "cam_link"; - } else if (session.videoDevice == "ndi") { - session.videoDevice = "newtek_ndi_video"; - } else if (session.videoDevice == "") { - session.videoDevice = 1; - } else if (session.videoDevice == "1") { - session.videoDevice = 1; - } else if (session.videoDevice == "default") { - session.videoDevice = 1; - } else { - // whatever the user entered I guess, santitized. - session.videoDevice = session.videoDevice.replace(/[\W]+/g, "_").toLowerCase(); - } - - if (session.videoDevice === 0) { - getById("add_camera").innerHTML = "Share your Microphone"; - miniTranslate(getById("add_camera"), "share-your-mic"); - } - - getById("videoMenu").style.display = "none"; - log("session.videoDevice:" + session.videoDevice); -} - -// audioDevice -if (urlParams.has('audiodevice') || urlParams.has('adevice') || urlParams.has('ad') || urlParams.has('device') || urlParams.has('d')) { - - session.audioDevice = urlParams.get("audiodevice") || urlParams.get("adevice") || urlParams.get("ad") || urlParams.get("device") || urlParams.get("d"); - - if (session.audioDevice === null) { - session.audioDevice = "1"; - } else if (session.audioDevice) { - session.audioDevice = session.audioDevice.toLowerCase().replace(/[\W]+/g, "_"); - } - - if (session.audioDevice == "false") { - session.audioDevice = 0; - } else if (session.audioDevice == "0") { - session.audioDevice = 0; - } else if (session.audioDevice == "no") { - session.audioDevice = 0; - } else if (session.audioDevice == "off") { - session.audioDevice = 0; - } else if (session.audioDevice == "") { - session.audioDevice = 1; - } else if (session.audioDevice == "1") { - session.audioDevice = 1; - } else if (session.audioDevice == "default") { - session.audioDevice = 1; - } else if (session.audioDevice == "ndi") { - session.audioDevice = "line_newtek_ndi_audio"; - } else { - // whatever the user entered I guess - session.audioDevice = session.audioDevice.replace(/[\W]+/g, "_").toLowerCase(); - } - - - if (session.videoDevice === 0) { - if (session.audioDevice === 0) { - getById("add_camera").innerHTML = "Click Start to Join"; - miniTranslate(getById("add_camera"), "click-start-to-join"); - getById("container-2").className = 'column columnfade advanced'; // Hide screen share on mobile - getById("container-3").classList.add("skip-animation"); - getById("container-3").classList.remove('pointer'); - setTimeout(function() { - previewWebcam(); - }, 100); - session.webcamonly = true; - } - } - - log("session.audioDevice:" + session.audioDevice); - - getById("audioMenu").style.display = "none"; - getById("headphonesDiv").style.display = "none"; - getById("headphonesDiv2").style.display = "none"; - getById("audioScreenShare1").style.display = "none"; - -} - - -if (urlParams.has('autojoin') || urlParams.has('autostart') || urlParams.has('aj') || urlParams.has('as')) { - session.autostart = true; - if (session.screenshare) { - setTimeout(function() { - publishScreen(); - }, 2000); - } -} - -if (urlParams.has('noiframe') || urlParams.has('noiframes') || urlParams.has('nif')) { - - session.noiframe = urlParams.get('noiframe') || urlParams.get('noiframes') || urlParams.get('nif'); - - if (!(session.noiframe)) { - session.noiframe = []; - } else { - session.noiframe = session.noiframe.split(","); - } - log("disable iframe playback"); - log(session.noiframe); -} - - -if (urlParams.has('exclude') || urlParams.has('ex')) { - - session.exclude = urlParams.get('exclude') || urlParams.get('ex'); - - if (!(session.exclude)) { - session.exclude = false; - } else { - session.exclude = session.exclude.split(","); - } - log("exclude video playback"); - log(session.exclude); -} - - -if (urlParams.has('novideo') || urlParams.has('nv') || urlParams.has('hidevideo') || urlParams.has('showonly')) { - - session.novideo = urlParams.get('novideo') || urlParams.get('nv') || urlParams.get('hidevideo') || urlParams.get('showonly'); - - if (!(session.novideo)) { - session.novideo = []; - } else { - session.novideo = session.novideo.split(","); - } - log("disable video playback"); - log(session.novideo); -} - -if (urlParams.has('noaudio') || urlParams.has('na') || urlParams.has('hideaudio')) { - - session.noaudio = urlParams.get('noaudio') || urlParams.get('na') || urlParams.get('hideaudio'); - - if (!(session.noaudio)) { - session.noaudio = []; - } else { - session.noaudio = session.noaudio.split(","); - } - log("disable audio playback"); -} - -if (urlParams.has('forceios')) { - log("allow iOS to work in video group chat; for this user at least"); - session.forceios = true; -} - -if (urlParams.has('nocursor')) { - session.nocursor = true; - log("DISABLE CURSOR"); - var style = document.createElement('style'); - style.innerHTML = ` - video { - margin: 0; - padding: 0; - overflow: hidden; - cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=), none; - user-select: none; - } - `; - document.head.appendChild(style); - -} - -if (urlParams.has('vbr')) { - session.cbr = 0; -} - -if (urlParams.has('order')) { - session.order = parseInt(urlParams.get('order')) || 0; -} -if (urlParams.has('sensors') || urlParams.has('sensor') || urlParams.has('gyro') || urlParams.has('gyros') || urlParams.has('accelerometer')) { - session.sensorData = urlParams.get('sensors') || urlParams.get('sensor') || urlParams.get('gyro') || urlParams.get('gyros') || urlParams.get('accelerometer') || 30; - session.sensorData = parseInt(session.sensorData); -} - -if (urlParams.has('minptime')) { - session.minptime = parseInt(urlParams.get('minptime')) || 10; - if (session.minptime < 10) { - session.minptime = 10; - } - if (session.minptime > 300) { - session.minptime = 300; - } -} - -if (urlParams.has('maxptime')) { - session.maxptime = parseInt(urlParams.get('maxptime')) || 60; - if (session.maxptime < 10) { - session.maxptime = 10; - } - if (session.maxptime > 300) { - session.maxptime = 300; - } -} - -if (urlParams.has('ptime')) { - session.ptime = parseInt(urlParams.get('ptime')) || 20; - if (session.minptime < 10) { - session.ptime = 10; - } - if (session.minptime > 300) { - session.ptime = 300; - } -} - - -if (urlParams.has('codec')) { - log("CODEC CHANGED"); - session.codec = urlParams.get('codec').toLowerCase(); - if (session.codec=="webp"){ - session.webp = true; - session.codec = false; - } -} else if (isOperaGX()){ - session.codec = "vp8"; - warnlog("Defaulting to VP8 manually, as H264 with remote iOS devices is not supported"); -} - -if (urlParams.has('nonacks')){ // disables error control / throttling. - session.noNacks = true; -} -if (urlParams.has('nopli')){ // disables error control / throttling. - session.noPLIs = true; -} -if (urlParams.has('noremb')){ // disables error control / throttling. - session.noREMB = true; -} - -if (urlParams.has('scale')) { - if (urlParams.get('scale') == "false") {} else if (urlParams.get('scale') == "0") {} else if (urlParams.get('scale') == "no") {} else if (urlParams.get('scale') == "off") {} else { - log("Resolution scale requested"); - session.scale = parseInt(urlParams.get('scale')) || 100; - } - session.dynamicScale = false; // default true -} - -var ConfigSettings = getById("main-js"); -var ln_template = false; -var translation = false; -try { - if (ConfigSettings) { - ln_template = ConfigSettings.getAttribute('data-translation'); // Translations - if (typeof ln_template === "undefined") { - ln_template = false; - } else if (ln_template === null) { - ln_template = false; - } - } - - if (urlParams.has('ln')) { - ln_template = urlParams.get('ln'); - } -} catch (e) { - errorlog(e); -} - -if (ln_template) { // checking if manual lanuage override enabled - try { - log("Template: " + ln_template); - fetch("./translations/" + ln_template + '.json').then(function(response) { - if (response.status !== 200) { - log('Looks like there was a problem. Status Code: ' + - response.status); - return; - } - response.json().then(function(data) { - log(data); - translation = data; - var trans = data.innerHTML; - var allItems = document.querySelectorAll('[data-translate]'); - allItems.forEach(function(ele) { - if (ele.dataset.translate in trans) { - ele.innerHTML = trans[ele.dataset.translate]; - } - }); - trans = data.titles; - var allTitles = document.querySelectorAll('[title]'); - allTitles.forEach(function(ele) { - var key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.title = trans[key]; - } - }); - trans = data.placeholders; - var allPlaceholders = document.querySelectorAll('[placeholder]'); - allPlaceholders.forEach(function(ele) { - var key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.placeholder = trans[key]; - } - }); - - - getById("mainmenu").style.opacity = 1; - }).catch(function(err) { - errorlog(err); - getById("mainmenu").style.opacity = 1; - }); - }).catch(function(err) { - errorlog(err); - getById("mainmenu").style.opacity = 1; - }); - - } catch (error) { - errorlog(error); - getById("mainmenu").style.opacity = 1; - } -} else if (location.hostname !== "obs.ninja") { - if (location.hostname === "rtc.ninja"){ - try { - if (session.label === false) { - document.title = ""; - } - getById("qos").innerHTML = ""; - getById("logoname").innerHTML = ""; - getById("helpbutton").style.display = "none"; - getById("helpbutton").style.opacity = 0; - getById("reportbutton").style.display = "none"; - getById("reportbutton").style.opacity = 0; - getById("mainmenu").style.opacity = 1; - getById("mainmenu").style.margin = "30px 0"; - getById("translateButton").style.display = "none"; - getById("translateButton").style.opacity = 0; - getById("info").style.display = "none"; - getById("info").style.opacity = 0; - getById("chatBody").innerHTML = ""; - } catch (e) {} - } - try { - fetch("./translations/blank.json").then(function(response) { - if (response.status !== 200) { - log('Looks like there was a problem. Status Code: ' + - response.status); - return; - } - response.json().then(function(data) { - log(data); - - var trans = data.innerHTML; - var allItems = document.querySelectorAll('[data-translate]'); - allItems.forEach(function(ele) { - if (ele.dataset.translate in trans) { - ele.innerHTML = trans[ele.dataset.translate]; - } - }); - trans = data.titles; - var allTitles = document.querySelectorAll('[title]'); - allTitles.forEach(function(ele) { - var key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.title = trans[key]; - } - }); - trans = data.placeholders; - var allPlaceholders = document.querySelectorAll('[placeholder]'); - allPlaceholders.forEach(function(ele) { - var key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.placeholder = trans[key]; - } - }); - - if (session.label === false) { - document.title = location.hostname; - } - getById("qos").innerHTML = location.hostname; - getById("logoname").innerHTML = getById("qos").outerHTML; - getById("helpbutton").style.display = "none"; - getById("reportbutton").style.display = "none"; - getById("mainmenu").style.opacity = 1; - }).catch(function(err) { - errorlog(err); - getById("mainmenu").style.opacity = 1; - }); - }).catch(function(err) { - errorlog(err); - getById("mainmenu").style.opacity = 1; - }); - if (session.label === false) { - document.title = location.hostname; - } - getById("qos").innerHTML = location.hostname; - getById("logoname").innerHTML = getById("qos").outerHTML; - getById("helpbutton").style.display = "none"; - getById("reportbutton").style.display = "none"; - getById("chatBody").innerHTML = ""; - } catch (error) { - errorlog(error); - } -} else { // check if automatic language translation is available - getById("mainmenu").style.opacity = 1; -} - -try { - if (location.hostname === "rtc.ninja"){ // an extra-brand-free version of OBS.Ninja - if (session.label === false) { - document.title = ""; - } - getById("qos").innerHTML = ""; - getById("logoname").innerHTML = ""; - getById("helpbutton").style.display = "none"; - getById("helpbutton").style.opacity = 0; - getById("reportbutton").style.display = "none"; - getById("reportbutton").style.opacity = 0; - getById("mainmenu").style.opacity = 1; - getById("mainmenu").style.margin = "30px 0"; - getById("translateButton").style.display = "none"; - getById("translateButton").style.opacity = 0; - getById("info").style.display = "none"; - getById("info").style.opacity = 0; - getById("chatBody").innerHTML = ""; - } else if (location.hostname !== "obs.ninja") { - if (session.label === false) { - document.title = location.hostname; - } - getById("qos").innerHTML = sanitizeLabel(location.hostname); - getById("logoname").innerHTML = getById("qos").outerHTML; - getById("helpbutton").style.display = "none"; - getById("reportbutton").style.display = "none"; - } - -} catch (e) {} - -if (isIFrame) { - getById("helpbutton").style.display = "none"; - getById("helpbutton").style.opacity = 0; - getById("reportbutton").style.display = "none"; - getById("reportbutton").style.opacity = 0; - getById("chatBody").innerHTML = ""; -} - -function miniTranslate(ele, ident = false) { - if (ident) { - ele.dataset.translate = ident; - } else { - ident = ele.dataset.translate; - } - try { - if (ident in translation.innerHTML) { - ele.innerHTML = translation.innerHTML[ident]; - } - } catch (e) {} -} - -function changeLg(lang) { - fetch("./translations/" + lang + '.json').then(function(response) { - if (response.status !== 200) { - logerror('Language translation file not found.' + response.status); - return; - } - response.json().then(function(data) { - log(data); - translation = data; // translation.innerHTML[ele.dataset.translate] - var trans = data.innerHTML; - var allItems = document.querySelectorAll('[data-translate]'); - allItems.forEach(function(ele) { - if (ele.dataset.translate in trans) { - ele.innerHTML = trans[ele.dataset.translate]; - } - }); - trans = data.titles; - var allTitles = document.querySelectorAll('[title]'); - allTitles.forEach(function(ele) { - var key = ele.title.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.title = trans[key]; - } - }); - trans = data.placeholders; - var allPlaceholders = document.querySelectorAll('[placeholder]'); - allPlaceholders.forEach(function(ele) { - var key = ele.placeholder.replace(/[\W]+/g, "-").toLowerCase(); - if (key in trans) { - ele.placeholder = trans[key]; - } - }); - }); - }).catch(function(err) { - errorlog(err); - }); -} - -if (urlParams.has('beep') || urlParams.has('notify') || urlParams.has('tone')) { - session.beepToNotify = true; -} - -if (urlParams.has('r2d2')) { - getById("testtone").innerHTML = ""; - getById("testtone").src = "./media/robot.mp3"; - session.beepToNotify = true; -} - -if (urlParams.has('videobitrate') || urlParams.has('bitrate') || urlParams.has('vb')) { - session.bitrate = urlParams.get('videobitrate') || urlParams.get('bitrate') || urlParams.get('vb'); - if (session.bitrate) { - if ((session.view_set) && (session.bitrate.split(",").length > 1)) { - session.bitrate_set = session.bitrate.split(","); - session.bitrate = parseInt(session.bitrate_set[0]); - } else { - session.bitrate = parseInt(session.bitrate); - } - if (session.bitrate < 1) { - session.bitrate = false; - } - log("BITRATE ENABLED"); - log(session.bitrate); - - } -} - -if (urlParams.has('maxvideobitrate') || urlParams.has('maxbitrate') || urlParams.has('mvb')) { - session.maxvideobitrate = urlParams.get('maxvideobitrate') || urlParams.get('maxbitrate') || urlParams.get('mvb'); - session.maxvideobitrate = parseInt(session.maxvideobitrate); - - if (session.maxvideobitrate < 1) { - session.maxvideobitrate = false; - } - log("maxvideobitrate ENABLED"); - log(session.maxvideobitrate); -} - -if (urlParams.has('totalroombitrate') || urlParams.has('totalroomvideobitrate') || urlParams.has('trb')) { - session.totalRoomBitrate = urlParams.get('totalroombitrate') || urlParams.get('totalroomvideobitrate') || urlParams.get('trb'); - session.totalRoomBitrate = parseInt(session.totalRoomBitrate); - - if (session.totalRoomBitrate < 1) { - session.totalRoomBitrate = false; - } - log("totalRoomBitrate ENABLED"); - log(session.totalRoomBitrate); - -} -if (session.totalRoomBitrate===false){ - session.totalRoomBitrate = session.totalRoomBitrate_default; -} else { - session.totalRoomBitrate_default = session.totalRoomBitrate; // trb_default doesn't change dynamically, but trb can (per director I guess) -} - - -if (urlParams.has('limittotalbitrate') || urlParams.has('ltb')){ - session.limitTotalBitrate = urlParams.get('limittotalbitrate') || urlParams.get('ltb') || 2500; - session.limitTotalBitrate = parseInt(session.limitTotalBitrate); -} - - - -if (urlParams.has('height') || urlParams.has('h')) { - session.height = urlParams.get('height') || urlParams.get('h'); - session.height = parseInt(session.height); -} - -if (urlParams.has('width') || urlParams.has('w')) { - session.width = urlParams.get('width') || urlParams.get('w'); - session.width = parseInt(session.width); -} - -if (urlParams.has('quality') || urlParams.has('q')) { - try { - session.quality = urlParams.get('quality') || urlParams.get('q') || 0; - session.quality = parseInt(session.quality); - getById("gear_screen").parentNode.removeChild(getById("gear_screen")); - getById("gear_webcam").parentNode.removeChild(getById("gear_webcam")); - } catch (e) { - errorlog(e); - } -} - -if (urlParams.has('sink')) { - session.sink = urlParams.get('sink'); -} else if (urlParams.has('outputdevice') || urlParams.has('od') || urlParams.has('audiooutput')) { - session.outputDevice = urlParams.get('outputdevice') || urlParams.get('od') || urlParams.get('audiooutput') || null; - - if (session.outputDevice) { - session.outputDevice = session.outputDevice.toLowerCase().replace(/[\W]+/g, "_"); - } else { - session.outputDevice = null; - getById("headphonesDiv3").style.display = "none"; // - } - - if (session.outputDevice) { - try { - enumerateDevices().then(function(deviceInfos) { - for (let i = 0; i !== deviceInfos.length; ++i) { - if (deviceInfos[i].kind === 'audiooutput') { - if (deviceInfos[i].label.replace(/[\W]+/g, "_").toLowerCase().includes(session.outputDevice)) { - session.sink = deviceInfos[i].deviceId; - log("AUDIO OUT DEVICE: " + deviceInfos[i].deviceId); - break; - } - } - } - }); - } catch (e) {} - } - - getById("headphonesDiv").style.display = "none"; - getById("headphonesDiv2").style.display = "none"; -} - -if (window.obsstudio || (navigator.userAgent.toLowerCase().indexOf(' electron/') > -1)){ - session.fullscreen = true; -} else if (urlParams.has('fullscreen')) { - session.fullscreen = true; -} - -if (urlParams.has('stats')) { - session.statsMenu = true; -} - - -if (urlParams.has('cleandirector') || urlParams.has('cdv')) { - session.cleanDirector = true; -} - - -if (session.cleanOutput){ - getById("translateButton").style.display = "none"; - getById("credits").style.display = "none"; - getById("header").style.display = "none"; - getById("controlButtons").style.display = "none"; - var style = document.createElement('style'); - style.innerHTML = ` - video { - background-image: none; - } - `; - document.head.appendChild(style); -} - -if (urlParams.has('cleanish')) { - session.cleanish = true; -} - -if (urlParams.has('channels')) { // must be loaded before channelOffset - session.audioChannels = parseInt(urlParams.get('channels')); - session.offsetChannel = 0; - log("max channels is 32; channels offset"); - session.audioEffects = true; -} -if (urlParams.has('channeloffset')) { - session.offsetChannel = parseInt(urlParams.get('channeloffset')); - log("max channels is 32; channels offset"); - session.audioEffects = true; -} - - - -if (urlParams.has('enhance')) { - //if (parseInt(urlParams.get('enhance')>0){ - session.enhance = true; //parseInt(urlParams.get('enhance')); - //} -} - -if (urlParams.has('maxviewers') || urlParams.has('mv')) { - - session.maxviewers = urlParams.get('maxviewers') || urlParams.get('mv'); - if (session.maxviewers.length == 0) { - session.maxviewers = 1; - } else { - session.maxviewers = parseInt(session.maxviewers); - } - log("maxviewers set"); -} - -if (urlParams.has('maxpublishers') || urlParams.has('mp')) { - - session.maxpublishers = urlParams.get('maxpublishers') || urlParams.get('mp'); - if (session.maxpublishers.length == 0) { - session.maxpublishers = 1; - } else { - session.maxpublishers = parseInt(session.maxpublishers); - } - log("maxpublishers set"); -} - -if (urlParams.has('maxconnections') || urlParams.has('mc')) { - - session.maxconnections = urlParams.get('maxconnections') || urlParams.get('maxconnections'); - if (session.maxconnections.length == 0) { - session.maxconnections = 1; - } else { - session.maxconnections = parseInt(session.maxconnections); - } - - log("maxconnections set"); -} - - -if (urlParams.has('secure')) { - session.security = true; - if (!(session.cleanOutput)) { - setTimeout(function() { - warnUser("Enhanced Security Mode Enabled."); - }, 100); - } -} - -if (urlParams.has('random') || urlParams.has('randomize')) { - session.randomize = true; -} - -if (urlParams.has('framerate') || urlParams.has('fr') || urlParams.has('fps')) { - session.framerate = urlParams.get('framerate') || urlParams.get('fr') || urlParams.get('fps'); - session.framerate = parseInt(session.framerate); - log("framerate Changed"); - log(session.framerate); -} - -if (urlParams.has('maxframerate') || urlParams.has('mfr') || urlParams.has('mfps')) { - session.maxframerate = urlParams.get('maxframerate') || urlParams.get('mfr') || urlParams.get('mfps'); - session.maxframerate = parseInt(session.maxframerate); - log("max framerate assigned"); - log(session.maxframerate); -} - -if (urlParams.has('buffer')) { // needs to be before sync - session.buffer = parseFloat(urlParams.get('buffer')) || 0; - log("buffer Changed: " + session.buffer); - session.sync = 0; - session.audioEffects = true; -} - -if (urlParams.has('sync')) { - session.sync = parseFloat(urlParams.get('sync')); - log("sync Changed; in milliseconds. If not set, defaults to auto."); - log(session.sync); - session.audioEffects = true; - if (session.buffer === false) { - session.buffer = 0; - } -} - -if (urlParams.has('mirror')) { - if (urlParams.get('mirror') == "3") { - getById("main").classList.add("mirror"); - } else if (urlParams.get('mirror') == "2") { - session.mirrored = 2; - } else if (urlParams.get('mirror') == "0") { - session.mirrored = 0; - } else if (urlParams.get('mirror') == "false") { - session.mirrored = 0; - } else if (urlParams.get('mirror') == "off") { - session.mirrored = 0; - } else { - session.mirrored = 1; - } -} - -if (urlParams.has('flip')) { - if (urlParams.get('flip') == "0") { - session.flipped = false; - } else if (urlParams.get('flip') == "false") { - session.flipped = false; - } else if (urlParams.get('flip') == "off") { - session.flipped = false; - } else { - session.flipped = true; - } -} - -if ((session.mirrored) && (session.flipped)) { - try { - log("Mirror all videos"); - var mirrorStyle = document.createElement('style'); - mirrorStyle.innerHTML = "video {transform: scaleX(-1) scaleY(-1); }"; - document.getElementsByTagName("head")[0].appendChild(mirrorStyle); - } catch (e) { - errorlog(e); - } -} else if (session.mirrored) { // mirror the video horizontally - try { - log("Mirror all videos"); - var mirrorStyle = document.createElement('style'); - mirrorStyle.innerHTML = "video {transform: scaleX(-1);}"; - document.getElementsByTagName("head")[0].appendChild(mirrorStyle); - } catch (e) { - errorlog(e); - } -} else if (session.flipped) { // mirror the video vertically - try { - log("Mirror all videos"); - var mirrorStyle = document.createElement('style'); - mirrorStyle.innerHTML = "video {transform: scaleY(-1);}"; - document.getElementsByTagName("head")[0].appendChild(mirrorStyle); - } catch (e) { - errorlog(e); - } -} - - -if (urlParams.has('icefilter')) { - log("ICE FILTER ENABLED"); - session.icefilter = urlParams.get('icefilter'); -} - - -if (urlParams.has('effects') || urlParams.has('effect')) { - session.effects = urlParams.get('effects') || urlParams.get('effect') || null; - if (session.effects === null){ - getById("effectsDiv").style.display = "block"; - session.effects = 0; - } else if (session.effects === "0" || session.effects === "false" || session.effects === "off"){ - session.effects = false; - getById("effectSelector3").style.display = "none"; - getById("effectsDiv3").style.display = "none"; - getById("effectSelector").style.display = "none"; - getById("effectsDiv").style.display = "none"; - } else { - session.effects = parseInt(session.effects); - } - - if (session.effects === 5){ - getById("selectImageTFLITE").style.display = "block"; - getById("selectImageTFLITE3").style.display = "block"; - getById("effectSelector").style.display = "none"; - getById("effectsDiv").style.display = "block"; - } - // mirror == 2 - // face == 1 - // blur = 3 - // green = 4 - // image = 5 -} - -if (urlParams.has('activespeaker') || urlParams.has('speakerview') || urlParams.has('sas')){ - session.activeSpeaker = true; - session.audioEffects = true; - session.audioMeterGuest = true; - setInterval(function(){activeSpeaker(false);},100); -} - -if (urlParams.has('meter') || urlParams.has('meterstyle')){ - session.meterStyle = urlParams.get('meter') || urlParams.get('meterstyle') || 1; -} - -if (urlParams.has('directorchat') || urlParams.has('dc')){ - session.directorChat = true; -} - -if (urlParams.has('style') || urlParams.has('st')) { - session.style = urlParams.get('style') || urlParams.get('st') || 1; - if ((parseInt(session.style) == 1) || (session.style == "justvideo")) { // no audio only - session.style = 1; - } else if ((parseInt(session.style) == 2) || (session.style == "waveform")) { // audio waveform - session.style = 2; - session.audioEffects = true; ////!!!!!!! Do I want to enable the audioEffects myself? or do it here? - } else if ((parseInt(session.style) == 3) || (session.style == "volume")) { // photo is taken? upload option? canvas? - session.style = 3; - session.audioEffects = true; - } else { - session.style = 1; - } -} - - -if (urlParams.has('samplerate') || urlParams.has('sr')) { - session.sampleRate = parseInt(urlParams.get('samplerate')) || parseInt(urlParams.get('samplerate')) || 48000; - if (session.audioCtx) { - session.audioCtx.close(); // close the default audio context. - } - session.audioCtx = new AudioContext({ // create a new audio context with a higher sample rate. - sampleRate: session.sampleRate - }); - session.audioEffects = true; -} - - -if (urlParams.has('noaudioprocessing') || urlParams.has('noap')) { - session.disableWebAudio = true; // default true; might be useful to disable on slow or old computers? - session.audioEffects = false; // disable audio inbound effects also. - session.audioMeterGuest = false; -} - -if (urlParams.has('tcp')){ // forces the TURN servers to use TCP mode; still need to add &private to force TURN also tho - session.forceTcpMode = true; -} -if (urlParams.has('speedtest')){ // forces essentially UDP mode, unless TCP is specified, and some other stuff - session.speedtest = true; -} - -if (urlParams.has('turn')) { - var turnstring = urlParams.get('turn'); - if (turnstring == "twilio") { // a sample function on loading remote credentials for TURN servers. - try { - - session.ws = false; // prevents connection - var twillioRequest = new XMLHttpRequest(); - twillioRequest.onreadystatechange = function() { - if (twillioRequest.status === 200) { - try{ - var res = JSON.parse(twillioRequest.responseText); - } catch(e){return;} - session.configuration = { - iceServers: [{ - "username": res["1"], - "credential": res["2"], - "url": "turn:global.turn.twilio.com:3478?transport=tcp", - "urls": "turn:global.turn.twilio.com:3478?transport=tcp" - }, - { - "username": res["1"], - "credential": res["2"], - "url": "turn:global.turn.twilio.com:443?transport=tcp", - "urls": "turn:global.turn.twilio.com:443?transport=tcp" - } - ], - sdpSemantics: 'unified-plan' // future-proofing - }; - if (session.ws===false){ - session.ws=null; // allows connection (clears state) - session.connect(); // connect if not already connected. - } - } - // system does not connect if twilio API does not respond. - }; - twillioRequest.open('GET', 'https://api.obs.ninja:1443/twilio', true); // `false` makes the request synchronous - twillioRequest.send(); - - - } catch (e) { - errorlog("Twilio Failed"); - } - } else if (turnstring == "nostun") { // disable TURN servers - session.configuration = { - sdpSemantics: 'unified-plan' // future-proofing - }; - } else if ((turnstring == "false") || (turnstring == "off") || (turnstring == "0")) { // disable TURN servers - session.configuration = { - iceServers: [ - { urls: ["stun:stun.l.google.com:19302", "stun:stun4.l.google.com:19302"]} // more than 4 stun+turn servers will cause firefox issues? (2 + 2 for now then) - ], - sdpSemantics: 'unified-plan' // future-proofing - }; - } else { - try { - //session.configuration = {iceServers: [], sdpSemantics: 'unified-plan'}; - turnstring = turnstring.split(";"); - if (turnstring !== "false") { // false disables the TURN server. Useful for debuggin - var turn = {}; - turn.username = turnstring[0]; // myusername - turn.credential = turnstring[1]; //mypassword - turn.urls = [turnstring[2]]; // ["turn:turn.obs.ninja:443"]; - - session.configuration = { - iceServers: [ - { urls: ["stun:stun.l.google.com:19302", "stun:stun4.l.google.com:19302"]} // more than 4 stun+turn servers will cause firefox issues? (2 + 2 for now then) - ], - sdpSemantics: 'unified-plan' // future-proofing - }; - - session.configuration.iceServers.push(turn); - } - } catch (e) { - if (!(session.cleanOutput)) { - warnUser("TURN server parameters were wrong."); - } - errorlog(e); - } - } -} else { - chooseBestTURN(); // obs.ninja turn servers, if needed. -} - - -if (urlParams.has('privacy') || urlParams.has('private') || urlParams.has('relay')) { // please only use if you are also using your own TURN service. - session.privacy = true; - - try { - session.configuration.iceTransportPolicy = "relay"; // https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidate/address - } catch (e) { - if (!(session.cleanOutput)) { - warnUser("Privacy mode failed to configure."); - } - errorlog(e); - } - - if (session.speedtest){ - if (session.maxvideobitrate !== false) { - if (session.maxvideobitrate > 6000) { - session.maxvideobitrate = 6000; // Please feel free to get rid of this if using your own TURN servers... - } - } else { - session.maxvideobitrate = 6000; // don't let people pull more than 2500 from you - } - if (session.bitrate !== false) { - if (session.bitrate > 6000) { - session.bitrate = 6000; // Please feel free to get rid of this if using your own TURN servers... - } - } - } else { - if (session.maxvideobitrate !== false) { - if (session.maxvideobitrate > 2500) { - session.maxvideobitrate = 2500; // Please feel free to get rid of this if using your own TURN servers... - } - } else { - session.maxvideobitrate = 2500; // don't let people pull more than 2500 from you - } - if (session.bitrate !== false) { - if (session.bitrate > 2500) { - session.bitrate = 2500; // Please feel free to get rid of this if using your own TURN servers... - } - } - } -} - -if (urlParams.has('wss')) { - if (urlParams.get('wss')) { - session.wss = "wss://" + urlParams.get('wss'); - } -} - -if (urlParams.has('queue')) { - session.queue = true; -} - -if (isIFrame) { // reduce CPU load if not needed. - window.onmessage = function(e) { // iFRAME support - log(e); - try { - if ("function" in e.data) { // these are calling in-app functions, with perhaps a callback -- TODO: add callbacks - var ret = null; - if (e.data.function === "previewWebcam") { - ret = previewWebcam(); - } else if (e.data.function === "changeHTML") { - ret = getById(e.data.target); - ret.innerHTML = e.data.value; - } else if (e.data.function === "publishScreen") { - ret = publishScreen(); - } else if (e.data.function === "eval") { - eval(e.data.value); // eval == evil ; feedback welcomed - } - } - } catch (err) { - errorlog(err); - } - - if ("sendChat" in e.data) { - sendChat(e.data.sendChat); // sends to all peers; more options down the road - } - // Chat out gets called via getChatMessage function - // Related code: parent.postMessage({"chat": {"msg":-----,"type":----,"time":---} }, "*"); - - if ("mic" in e.data) { // this should work for the director's mic mute button as well. Needs to be manually enabled the first time still tho. - if (e.data.mic === true) { // unmute - session.muted = false; // set - log(session.muted); - toggleMute(true); // apply - } else if (e.data.mic === false) { // mute - session.muted = true; // set - log(session.muted); - toggleMute(true); // apply - } else if (e.data.mic === "toggle") { // toggle - toggleMute(); - } - } - - if ("camera" in e.data) { // this should work for the director's mic mute button as well. Needs to be manually enabled the first time still tho. - if (e.data.camera === true) { // unmute - session.videoMuted = false; // set - log(session.videoMuted); - toggleVideoMute(true); // apply - } else if (e.data.camera === false) { // mute - session.videoMuted = true; // set - log(session.videoMuted); - toggleVideoMute(true); // apply - } else if (e.data.camera === "toggle") { // toggle - toggleVideoMute(); - } - } - - if ("keyframe" in e.data) { - session.sendKeyFrameScenes(); - } - - if ("mute" in e.data) { - if (e.data.mute === true) { // unmute - session.speakerMuted = true; // set - toggleSpeakerMute(true); // apply - } else if (e.data.mute === false) { // mute - session.speakerMuted = false; // set - toggleSpeakerMute(true); // apply - } else if (e.data.mute === "toggle") { // toggle - toggleSpeakerMute(); - } - } else if ("speaker" in e.data) { // same thing as mute. - if (e.data.speaker === true) { // unmute - session.speakerMuted = false; // set - toggleSpeakerMute(true); // apply - } else if (e.data.speaker === false) { // mute - session.speakerMuted = true; // set - toggleSpeakerMute(true); // apply - } else if (e.data.speaker === "toggle") { // toggle - toggleSpeakerMute(); - } - } - - if ("record" in e.data) { - if (e.data.record == false) { // mute - if ("recording" in session.videoElement) { - recordLocalVideo("stop"); - } - } else if (e.data.record == true){ - if ("recording" in session.videoElement) { - // already recording - } else { - recordLocalVideo("start"); - } - } - } - - - if ("volume" in e.data) { - for (var i in session.rpcs) { - try { - session.rpcs[i].videoElement.volume = parseFloat(e.data.volume); - } catch (e) { - errorlog(e); - } - } - } - - if ("bitrate" in e.data) { - for (var i in session.rpcs) { - try { - session.requestRateLimit(parseInt(e.data.bitrate), i); - } catch (e) { - errorlog(e); - } - } - } - - if ("audiobitrate" in e.data) { - for (var i in session.rpcs) { - try { - session.requestAudioRateLimit(parseInt(e.data.audiobitrate), i); - } catch (e) { - errorlog(e); - } - } - } - - if ("changeVideoDevice" in e.data) { - warnlog(e.data.changeVideoDevice); - changeVideoDevice(e.data.changeVideoDevice); - } - - if ("changeAudioDevice" in e.data) { - warnlog(e.data.changeAudioDevice); - changeAudioDevice(e.data.changeAudioDevice); - } - - - if ("sceneState" in e.data) { // TRUE OR FALSE - tells the connected peers if they are live or not via a tally light change. - - var visibility = e.data.sceneState; - - if (session.obsState.visibility !== visibility) { // only move forward if there is a change; the event likes to double fire you see. - session.obsStateSync(); - } - } - - if ("sendMessage" in e.data) { // webrtc send to viewers - session.sendMessage(e.data); - } - - if ("sendRequest" in e.data) { // webrtc send to publishers - session.sendRequest(e.data); - } - - if ("sendPeers" in e.data) { // webrtc send message to every connected peer; like send and request; a hammer vs a knife. - session.sendPeers(e.data); - } - - if ("reload" in e.data) { - location.reload(); - } - - if ("getStats" in e.data) { - - var stats = {}; - stats.total_outbound_connections = Object.keys(session.pcs).length; - stats.total_inbound_connections = Object.keys(session.rpcs).length; - stats.inbound_stats = {}; - for (var i in session.rpcs) { - stats.inbound_stats[session.rpcs[i].streamID] = session.rpcs[i].stats; - } - - - for (var uuid in session.pcs) { - setTimeout(function(UUID) { - session.pcs[UUID].getStats().then(function(stats) { - stats.forEach(stat => { - if (stat.type == "outbound-rtp") { - if (stat.kind == "video") { - - if ("qualityLimitationReason" in stat) { - session.pcs[UUID].stats.quality_limitation_reason = stat.qualityLimitationReason; - } - if ("framesPerSecond" in stat) { - session.pcs[UUID].stats.resolution = stat.frameWidth + " x " + stat.frameHeight + " @ " + stat.framesPerSecond; - } - if ("encoderImplementation" in stat) { - session.pcs[UUID].stats.encoder = stat.encoderImplementation; - } - } - } else if (stat.type == "remote-candidate") { - if ("relayProtocol" in stat) { - if ("ip" in stat) { - session.pcs[UUID].stats.remote_relay_IP = stat.ip; - } - session.pcs[UUID].stats.remote_relayProtocol = stat.relayProtocol; - } - if ("candidateType" in stat) { - session.pcs[UUID].stats.remote_candidateType = stat.candidateType; - } - } else if (stat.type == "local-candidate") { - if ("relayProtocol" in stat) { - if ("ip" in stat) { - session.pcs[UUID].stats.local_relayIP = stat.ip; - } - session.pcs[UUID].stats.local_relayProtocol = stat.relayProtocol; - } - if ("candidateType" in stat) { - session.pcs[UUID].stats.local_candidateType = stat.candidateType; - } - } else if ((stat.type == "candidate-pair" ) && (stat.nominated)) { - - if ("availableOutgoingBitrate" in stat){ - session.pcs[UUID].stats.available_outgoing_bitrate_kbps = parseInt(stat.availableOutgoingBitrate/1024); - } - if ("totalRoundTripTime" in stat){ - if ("responsesReceived" in stat){ - session.pcs[UUID].stats.average_roundTripTime_ms = parseInt((stat.totalRoundTripTime/stat.responsesReceived)*1000); - } - - } - } - return; - }); - return; - }); - }, 0, uuid); - } - setTimeout(function() { - stats.outbound_stats = {}; - for (var i in session.pcs) { - stats.outbound_stats[i] = session.pcs[i].stats; - } - parent.postMessage({ - "stats": stats - }, "*"); - }, 1000); - } - - if ("getRemoteStats" in e.data) { - session.sendRequest({"requestStats":true, "remote":session.remote}); - } - - if ("getLoudness" in e.data) { - log("GOT LOUDNESS REQUEST"); - if (e.data.getLoudness == true) { - session.pushLoudness = true; - var loudness = {}; - - for (var i in session.rpcs) { - loudness[session.rpcs[i].streamID] = session.rpcs[i].stats.Audio_Loudness; - } - - parent.postMessage({ - "loudness": loudness - }, "*"); - - } else { - session.pushLoudness = false; - } - } - - if ("getStreamIDs" in e.data) { - if (e.data.getStreamIDs == true) { - var streamIDs = {}; - for (var i in session.rpcs) { - streamIDs[session.rpcs[i].streamID] = session.rpcs[i].label; - } - parent.postMessage({ - "streamIDs": streamIDs - }, "*"); - - } - } - - if ("close" in e.data) { - for (var i in session.rpcs) { - try { - session.rpcs[i].close(); - } catch (e) { - errorlog(e); - } - } - } - - if ("style" in e.data) { - try { - const style = document.createElement('style'); - style.textContent = e.data.style; - document.head.append(style); - log(style); - } catch (e) { - errorlog(e); - } - } - - - if ("automixer" in e.data) { - if (e.data.automixer == true) { - session.manual = false; - try { - updateMixer(); - } catch (e) {} - } else if (e.data.automixer == false) { - session.manual = true; - } - } - - if ("target" in e.data) { - log(e.data); - for (var i in session.rpcs) { - try { - if ("streamID" in session.rpcs[i]) { - if ((session.rpcs[i].streamID == e.data.target) || (e.data.target == "*")) { - try { - if ("settings" in e.data) { - for (const property in e.data.settings) { - session.rpcs[i].videoElement[property] = e.data.settings[property]; - } - } - if ("add" in e.data) { - getById("gridlayout").appendChild(session.rpcs[i].videoElement); - - } else if ("remove" in e.data) { - try { - session.rpcs[i].videoElement.parentNode.removeChild(session.rpcs[i].videoElement); - } catch (e) { - try { - session.rpcs[i].videoElement.parentNode.parentNode.removeChild(session.rpcs[i].videoElement.parentNode); - } catch (e) {} - } - } - } catch (e) { - errorlog(e); - } - } - } - } catch (e) { - errorlog(e); - } - } - } - }; -} - -function setupIncomingVideoTracking(v, UUID){ // video element. - - if (session.directorUUID===UUID){ - v.muted=false; - } else { - v.muted = session.speakerMuted; - } - - v.onpause = (event) => { // prevent things from pausing; human or other - if (!((event.ctrlKey) || (event.metaKey) )){ - warnlog("Video paused; force it to play again"); - //return; - //session.audioCtx.resume(); - //log("ctx resume"); - - event.currentTarget.play().then(_ => { - log("playing"); - }).catch(error => { - warnlog("didnt play 1"); - }); - - } - } - - v.onplay = function(){ - try { - var bigPlayButton = document.getElementById("bigPlayButton"); - if (bigPlayButton){ - bigPlayButton.parentNode.removeChild(bigPlayButton); - } - } catch(e){} - if (session.pip){ - if (v.readyState >= 3){ - if (!(v.pip)){ - v.pip=true; - toggleSystemPip(v, true); - } - } - } - - } - - if (session.pip){ - v.onloadedmetadata = function(){ - if (!v.paused){ - if (!(v.pip)){ - v.pip=true; - toggleSystemPip(v, true); - } - } - } - } - - - v.addEventListener('resize', (e) => { - log("resize event"); - var aspectRatio = parseFloat(e.target.videoWidth/e.target.videoHeight); - if (v.dataset.aspectRatio){ - if (aspectRatio != v.dataset.aspectRatio){ - setTimeout(function(){updateMixer();},1); // We don't want to run this on the first resize? just subsequent ones. - } - } else { - log("ASPECT RATIO CHANGED"); - setTimeout(function(){updateMixer();},1); - } - v.dataset.aspectRatio = parseFloat(e.target.videoWidth/e.target.videoHeight); - }); - - v.volume = 1.0; // play audio automatically - v.autoplay = true; - v.controls = false; - v.classList.add("tile"); - v.setAttribute("playsinline",""); - v.controlTimer = null; - - changeAudioOutputDevice(v); // if enabled, changes to desired output audio device. - - if (document.getElementById("mainmenu")){ - var m = getById("mainmenu"); - m.remove(); - } - - if (session.director){ - v.controls = true; - var container = getById("videoContainer_"+UUID); - v.disablePictureInPicture = false - v.setAttribute("controls","controls") - container.appendChild(v); - session.requestRateLimit(session.directorViewBitrate,UUID); /// limit resolution for director - - if (session.beepToNotify) { - playtone(); - } - - } else if (session.scene!==false){ - v.controls = false; - - if (session.view){ // specific video to be played - v.style.display="block"; - } else if (session.scene==="0"){ - v.style.display="block"; - } else { // group scene I guess; needs to be added manually - v.style.display="none"; - v.muted= true; - } - - setTimeout(function(){updateMixer();},1); - } else if (session.roomid!==false){ - if (session.cleanOutput){ - v.controls = false; - } else if (window.obsstudio) { - v.controls = false; - } else { - v.controls = true; - } - if ((session.roomid==="") && (session.bitrate)){ - // let's keep the default bitrates, since this isn't a real room and bitrates are specified. - } else if (session.novideo !== false){ - if (session.novideo.includes(session.rpcs[UUID].streamID)){ - session.requestRateLimit(0,UUID);// limit resolution for guests see ln: 1804 in main.js also - } - } else { - session.requestRateLimit(0,UUID);// limit resolution for guests see ln: 1804 in main.js also - } - setTimeout(function(){updateMixer();},1); - } else { - v.style.display="block"; - if (window.obsstudio) { - v.controls = false; - } - setTimeout(function(){updateMixer();},1); - } - - - v.addEventListener('click', function(e) { // show stats of video if double clicked - log("clicked"); - try { - if ((e.ctrlKey)||(e.metaKey)){ - e.preventDefault(); - var uid = e.currentTarget.dataset.UUID; - if ("stats" in session.rpcs[uid]){ - - var [menu, innerMenu] = statsMenuCreator(); - - printViewStats(innerMenu, uid ); - - menu.interval = setInterval(printViewStats,3000, innerMenu, uid); - - - } - e.stopPropagation(); - return false; - } - } catch(e){errorlog(e);} - }); - - if (session.statsMenu){ - if ("stats" in session.rpcs[UUID]){ - - if (getById("menuStatsBox")){ - clearInterval(getById("menuStatsBox").interval); - getById("menuStatsBox").remove(); - } - - var [menu, innerMenu] = statsMenuCreator(); - - printViewStats(innerMenu, UUID ); - - menu.interval = setInterval(printViewStats,3000, innerMenu, UUID); - - } - } - - - v.touchTimeOut = null; - v.touchLastTap = 0; - v.touchCount = 0; - v.addEventListener('touchend', function(event) { - log("touched"); - - document.ontouchup = null; - document.onmouseup = null; - document.onmousemove = null; - document.ontouchmove = null; - - var currentTime = new Date().getTime(); - var tapLength = currentTime - v.touchLastTap; - clearTimeout(v.touchTimeOut); - if (tapLength < 500 && tapLength > 0) { - /// - log("double touched"); - v.touchCount+=1; - event.preventDefault(); - if (v.touchCount<5){ - v.touchLastTap = currentTime; - return false; - } - v.touchLastTap = 0; - v.touchCount=0; - - log("double touched"); - var uid = event.currentTarget.dataset.UUID; - if ("stats" in session.rpcs[uid]){ - - var [menu, innerMenu] = statsMenuCreator(); - - printViewStats(innerMenu, uid ); - - menu.interval = setInterval(printViewStats,3000, innerMenu, uid); - - - } - event.stopPropagation(); - return false; - ////// - } else { - v.touchCount=1; - v.touchTimeOut = setTimeout(function(vv) { - clearTimeout(vv.touchTimeOut); - vv.touchLastTap = 0; - vv.touchCount=0; - }, 5000, v); - v.touchLastTap = currentTime; - } - - }); - - - if (session.remote){ - v.addEventListener("wheel", session.remoteControl); - } - - if (v.controls == false){ - v.addEventListener("click", function () { - if (v.paused){ - log("PLAYING MANUALLY?"); - v.play().then(_ => { - log("playing"); - }).catch(warnlog); - } - }); - if (session.nocursor==false){ // we do not want to show the controls. This is because MacOS + OBS does not work; so electron app needs this. - if (!(session.cleanOutput)){ - if (!(window.obsstudio)){ - if (v.controlTimer){ - clearInterval(v.controlTimer); - } - v.controlTimer = setTimeout(showControlBar.bind(null,v),3000); - //v.controlTimer = setTimeout(function (){v.controls=true;},3000); // 3 seconds before I enable the controls automatically. This way it doesn't auto appear during loading. 3s enough, right? - } - } - } - } - - if (session.fadein){ - v.classList.add("fadein"); // allows the video to fade in. - } - - setTimeout(session.processStats, 1000, UUID); - -} - -function updateMixerRun(e=false){ // this is the main auto-mixing code. It's a giant function that runs when there are changes to screensize, video track statuses, etc. - if (getById("subControlButtons").dragElement){ - if (parseInt(getById("subControlButtons").style.top) > 0){ - getById("subControlButtons").style.top = "0px"; - } else if (parseInt(getById("subControlButtons").style.top) < parseInt(50 - window.innerHeight) ){ - getById("subControlButtons").style.top = parseInt( 50 - window.innerHeight)+"px"; - } - if (parseInt(getById("subControlButtons").style.left) < 0){ - getById("subControlButtons").style.left = "0px"; - } else if (parseInt(getById("subControlButtons").style.left) > parseInt( window.innerWidth - getById("subControlButtons").offsetWidth) ){ - getById("subControlButtons").style.left = parseInt( window.innerWidth -getById("subControlButtons").offsetWidth )+"px"; - } - } - if (session.director){return;} - if (session.manual === true){return;} - var playarea = getById("gridlayout"); - var header = getById("header"); - - var hi = header.offsetHeight ; - var w = window.innerWidth; - var h = window.innerHeight - hi; - - if ( window.innerHeight<=700 ){ - if (document.getElementById("controlButtons")){ - var h = window.innerHeight - hi - document.getElementById("controlButtons").offsetHeight; - } else { - var h = window.innerHeight - hi; - } - } - - var arW = 16.0; - var arH = 9.0; - - if (session.aspectratio){ - if (session.aspectratio==1){ - arW = 9.0; - arH = 16.0; - } else if (session.aspectratio==2){ - arW = 12.0; // square root; cause why not. - arH = 12.0; - } - } - - var ww = w/arW; - var hh = h/arH; - - var mediaPool = []; - var mediaPool_invisible = []; - - if (session.videoElement){ // I, myself, exist - if (session.videoElement.style.display!="none"){ // local feed - if (session.minipreview && (session.infocus!==true)){ - - session.videoElement.onclick = function(){ - if (session.infocus === true){ - session.infocus = false; - } else { - session.infocus = true; - log("session: myself"); - } - setTimeout(()=>updateMixer(),10); - }; - - } else { - if (session.order!==false){ - session.videoElement.order=session.order; - } else { - session.videoElement.order=0; - } - if (session.activeSpeaker && (!session.activelySpeaking)){ - mediaPool_invisible.push(session.videoElement); - } else { - mediaPool.push(session.videoElement); - } - } - } - } - - if (session.screenShareElement){ // I, myself, exist - if (session.screenShareElement.style.display!="none"){ // local feed - if (session.order!==false){ - session.screenShareElement.order=session.order; - } else { - session.screenShareElement.order=0; - } - - if (session.infocus!==false){ - mediaPool_invisible.push(session.screenShareElement); - } else if (session.activeSpeaker && (!session.activelySpeaking)){ - mediaPool_invisible.push(session.screenShareElement); - } else { - mediaPool.push(session.screenShareElement); - } - } - } - - if (session.iframeEle){ // I, myself, exist - if (session.iframeEle.style.display!="none"){ // local feed - if (session.order!==false){ - session.iframeEle.order=session.order; - } else { - session.iframeEle.order=0; - } - if (session.activeSpeaker && (!session.activelySpeaking)){ - mediaPool_invisible.push(session.iframeEle); - } else { - mediaPool.push(session.iframeEle); - } - } - } - - - if ((session.infocus) && (session.infocus in session.rpcs)){ // remote guest being full screened; infocus == UUID - log(session.infocus+" set fullscreen"); - mediaPool = []; // remove myself from fullscreen - for (var j in session.rpcs){ - if (j != session.infocus){ - session.requestRateLimit(0, j); // disable the video of non-fullscreen videos - try { - if (session.rpcs[j].videoElement.style.display!="none"){ // Add it if not hidden - mediaPool_invisible.push(session.rpcs[j].videoElement); - } - } catch(e){} - } else { // in focus video - //////// - try { - if (session.rpcs[j].order!==false){ - session.rpcs[j].videoElement.order=session.rpcs[j].order; - } else { - session.rpcs[j].videoElement.order=0; - } - /////////// - if (session.activeSpeaker && (!session.rpcs[j].activelySpeaking)){ - mediaPool_invisible.push(session.rpcs[j].videoElement); - } else { - mediaPool.push(session.rpcs[j].videoElement); - } - - session.rpcs[j].videoElement.style.visibility = "visible"; - if ((session.rpcs[j].targetBandwidth!==-1) && (session.rpcs[j].targetBandwidth